mirror of
https://github.com/rwinkhart/libmutton.git
synced 2026-09-06 00:57:17 -04:00
Implement utility function for formatting and printing errors
This commit is contained in:
@@ -13,8 +13,7 @@ import (
|
|||||||
func loadConfig() *ini.File {
|
func loadConfig() *ini.File {
|
||||||
cfg, err := ini.Load(ConfigPath)
|
cfg, err := ini.Load(ConfigPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(AnsiError+"Failed to load libmutton.ini:", err.Error()+AnsiReset)
|
PrintError("Failed to load libmutton.ini: "+err.Error(), ErrorRead, true)
|
||||||
os.Exit(ErrorRead)
|
|
||||||
}
|
}
|
||||||
return cfg
|
return cfg
|
||||||
}
|
}
|
||||||
@@ -38,14 +37,12 @@ func ParseConfig(valuesRequested [][2]string, missingValueError string) ([]strin
|
|||||||
switch missingValueError {
|
switch missingValueError {
|
||||||
case "":
|
case "":
|
||||||
err = fmt.Errorf("Failed to find value for key \"%s\" in section \"[%s]\" in libmutton.ini", pair[1], pair[0])
|
err = fmt.Errorf("Failed to find value for key \"%s\" in section \"[%s]\" in libmutton.ini", pair[1], pair[0])
|
||||||
fmt.Println(err.Error())
|
|
||||||
case "0":
|
case "0":
|
||||||
Exit(0) // hard (expected) exit for CLI; GUI/TUI continue silently
|
Exit(0) // hard (expected) exit for CLI; GUI/TUI continue silently
|
||||||
default:
|
default:
|
||||||
err = fmt.Errorf("%s", missingValueError)
|
err = fmt.Errorf("%s", missingValueError)
|
||||||
fmt.Println(err.Error())
|
|
||||||
}
|
}
|
||||||
Exit(ErrorRead) // hard exit for CLI; GUI/TUI continue silently
|
PrintError(err.Error(), ErrorRead, false)
|
||||||
// if interactive (soft exit), return nil and the error to be handled by the caller
|
// if interactive (soft exit), return nil and the error to be handled by the caller
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -63,8 +60,7 @@ func GenDeviceIDList(errorOnFail bool) *[]fs.DirEntry {
|
|||||||
deviceIDList, err := os.ReadDir(ConfigDir + PathSeparator + "devices")
|
deviceIDList, err := os.ReadDir(ConfigDir + PathSeparator + "devices")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errorOnFail {
|
if errorOnFail {
|
||||||
fmt.Println(AnsiError+"Failed to read the devices directory:", err.Error()+AnsiReset)
|
PrintError("Failed to read the devices directory: "+err.Error(), ErrorRead, true)
|
||||||
os.Exit(ErrorRead)
|
|
||||||
} else {
|
} else {
|
||||||
return nil // a nil return value indicates that the devices directory could not be read/does not exist
|
return nil // a nil return value indicates that the devices directory could not be read/does not exist
|
||||||
}
|
}
|
||||||
@@ -113,7 +109,6 @@ func WriteConfig(valuesToWrite [][3]string, keysToPrune [][2]string, append bool
|
|||||||
// save to libmutton.ini
|
// save to libmutton.ini
|
||||||
err := cfg.SaveTo(ConfigPath)
|
err := cfg.SaveTo(ConfigPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(AnsiError+"Failed to save libmutton.ini:", err.Error()+AnsiReset)
|
PrintError("Failed to save libmutton.ini: "+err.Error(), ErrorWrite, true)
|
||||||
os.Exit(ErrorWrite)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-10
@@ -23,8 +23,7 @@ func CopyArgument(targetLocation string, field int) {
|
|||||||
|
|
||||||
// ensure field is not empty
|
// ensure field is not empty
|
||||||
if decryptedEntry[field] == "" {
|
if decryptedEntry[field] == "" {
|
||||||
fmt.Println(AnsiError + "Field is empty" + AnsiReset)
|
PrintError("Field is empty", ErrorTargetNotFound, true)
|
||||||
os.Exit(ErrorTargetNotFound)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if field != 2 {
|
if field != 2 {
|
||||||
@@ -50,8 +49,7 @@ func CopyArgument(targetLocation string, field int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fmt.Println(AnsiError + "Field does not exist in entry" + AnsiReset)
|
PrintError("Field does not exist in entry", ErrorTargetNotFound, true)
|
||||||
os.Exit(ErrorTargetNotFound)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy field to clipboard, launch clipboard clearing process
|
// copy field to clipboard, launch clipboard clearing process
|
||||||
@@ -79,8 +77,7 @@ func clipClearProcess(assignedContents string) {
|
|||||||
clearClipboard := func() {
|
clearClipboard := func() {
|
||||||
err := cmdClear.Run()
|
err := cmdClear.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(AnsiError+"Failed to clear clipboard:", err.Error()+AnsiReset)
|
PrintError("Failed to clear clipboard", ErrorClipboard, true)
|
||||||
os.Exit(ErrorClipboard)
|
|
||||||
}
|
}
|
||||||
Exit(0)
|
Exit(0)
|
||||||
}
|
}
|
||||||
@@ -96,8 +93,7 @@ func clipClearProcess(assignedContents string) {
|
|||||||
|
|
||||||
newContents, err := cmdPaste.Output()
|
newContents, err := cmdPaste.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(AnsiError+"Failed to read clipboard contents:", err.Error()+AnsiReset)
|
PrintError("Failed to read clipboard contents", ErrorClipboard, true)
|
||||||
os.Exit(ErrorClipboard)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if assignedContents == strings.TrimRight(string(newContents), "\r\n") {
|
if assignedContents == strings.TrimRight(string(newContents), "\r\n") {
|
||||||
@@ -117,8 +113,7 @@ func GenTOTP(secret string, time time.Time, forSteam bool) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(AnsiError + "Error generating TOTP code" + AnsiReset)
|
PrintError("Error generating TOTP code", ErrorOther, true)
|
||||||
os.Exit(ErrorOther)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return totpToken
|
return totpToken
|
||||||
|
|||||||
+1
-4
@@ -3,8 +3,6 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -14,8 +12,7 @@ func copyString(continuous bool, copySubject string) {
|
|||||||
WriteToStdin(cmd, copySubject)
|
WriteToStdin(cmd, copySubject)
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(AnsiError+"Failed to copy to clipboard:", err.Error()+AnsiReset)
|
PrintError("Failed to copy to clipboard: "+err.Error(), ErrorClipboard, true)
|
||||||
os.Exit(ErrorClipboard)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !continuous {
|
if !continuous {
|
||||||
|
|||||||
+1
-4
@@ -3,8 +3,6 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -14,8 +12,7 @@ func copyString(continuous bool, copySubject string) {
|
|||||||
WriteToStdin(cmd, copySubject)
|
WriteToStdin(cmd, copySubject)
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(AnsiError+"Failed to copy to clipboard:", err.Error()+AnsiReset)
|
PrintError("Failed to copy to clipboard: "+err.Error(), ErrorClipboard, true)
|
||||||
os.Exit(ErrorClipboard)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !continuous {
|
if !continuous {
|
||||||
|
|||||||
+2
-5
@@ -3,7 +3,6 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
)
|
)
|
||||||
@@ -19,15 +18,13 @@ func copyString(continuous bool, copySubject string) {
|
|||||||
} else if _, envSet = os.LookupEnv("DISPLAY"); envSet {
|
} else if _, envSet = os.LookupEnv("DISPLAY"); envSet {
|
||||||
cmdCopy = exec.Command("xclip", "-sel", "c", "-t", "text/plain")
|
cmdCopy = exec.Command("xclip", "-sel", "c", "-t", "text/plain")
|
||||||
} else {
|
} else {
|
||||||
fmt.Println(AnsiError + "Clipboard platform could not be determined - Note that the clipboard does not function in a raw TTY" + AnsiReset)
|
PrintError("Clipboard platform could not be determined", ErrorClipboard, true)
|
||||||
os.Exit(ErrorClipboard)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteToStdin(cmdCopy, copySubject)
|
WriteToStdin(cmdCopy, copySubject)
|
||||||
err := cmdCopy.Run()
|
err := cmdCopy.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(AnsiError+"Failed to copy to clipboard:", err.Error()+AnsiReset)
|
PrintError("Failed to copy to clipboard: "+err.Error(), ErrorClipboard, true)
|
||||||
os.Exit(ErrorClipboard)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !continuous {
|
if !continuous {
|
||||||
|
|||||||
+1
-3
@@ -4,7 +4,6 @@ package core
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -14,8 +13,7 @@ func copyString(continuous bool, copySubject string) {
|
|||||||
cmd := exec.Command("powershell.exe", "-c", fmt.Sprintf("echo '%s' | Set-Clipboard", strings.ReplaceAll(copySubject, "'", "''")))
|
cmd := exec.Command("powershell.exe", "-c", fmt.Sprintf("echo '%s' | Set-Clipboard", strings.ReplaceAll(copySubject, "'", "''")))
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(AnsiError+"Failed to copy to clipboard:", err.Error()+AnsiReset)
|
PrintError("Failed to copy to clipboard: "+err.Error(), ErrorClipboard, true)
|
||||||
os.Exit(ErrorClipboard)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !continuous {
|
if !continuous {
|
||||||
|
|||||||
+2
-6
@@ -1,8 +1,6 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -18,8 +16,7 @@ func DecryptGPG(targetLocation string) []string {
|
|||||||
enableVirtualTerminalProcessing()
|
enableVirtualTerminalProcessing()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(AnsiError + "Failed to decrypt \"" + targetLocation + "\" - Ensure it is a valid GPG-encrypted file and that you entered your passphrase correctly" + AnsiReset)
|
PrintError("Failed to decrypt \""+targetLocation+"\" - Ensure it is a valid GPG-encrypted file and that you entered your passphrase correctly", ErrorDecryption, true)
|
||||||
os.Exit(ErrorDecryption)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.Split(string(output), "\n")
|
return strings.Split(string(output), "\n")
|
||||||
@@ -32,8 +29,7 @@ func EncryptGPG(input []string) []byte {
|
|||||||
WriteToStdin(cmd, strings.Join(input, "\n"))
|
WriteToStdin(cmd, strings.Join(input, "\n"))
|
||||||
encryptedBytes, err := cmd.Output()
|
encryptedBytes, err := cmd.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(AnsiError + "Failed to encrypt data - Ensure that your GPG key is valid and that you have a valid GPG ID set in libmutton.ini" + AnsiReset)
|
PrintError("Failed to encrypt data - Ensure that you have a valid GPG ID set in libmutton.ini", ErrorEncryption, true)
|
||||||
os.Exit(ErrorEncryption)
|
|
||||||
}
|
}
|
||||||
return encryptedBytes
|
return encryptedBytes
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-9
@@ -1,7 +1,6 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -45,8 +44,7 @@ func GpgKeyGen() string {
|
|||||||
cmd.Stdin = os.Stdin
|
cmd.Stdin = os.Stdin
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(AnsiError+"Failed to generate GPG key:", err.Error()+AnsiReset)
|
PrintError("Failed to generate GPG key: "+err.Error(), ErrorOther, true)
|
||||||
os.Exit(ErrorOther)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return "libmutton-" + unixTime + " (gpg-libmutton) <github.com/rwinkhart/libmutton>"
|
return "libmutton-" + unixTime + " (gpg-libmutton) <github.com/rwinkhart/libmutton>"
|
||||||
@@ -58,8 +56,7 @@ func DirInit(preserveOldConfigDir bool) string {
|
|||||||
// create EntryRoot
|
// create EntryRoot
|
||||||
err := os.MkdirAll(EntryRoot, 0700)
|
err := os.MkdirAll(EntryRoot, 0700)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(AnsiError+"Failed to create \""+EntryRoot+"\":", err.Error()+AnsiReset)
|
PrintError("Failed to create \""+EntryRoot+"\": "+err.Error(), ErrorWrite, true)
|
||||||
os.Exit(ErrorWrite)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get old device ID before its potential removal
|
// get old device ID before its potential removal
|
||||||
@@ -77,8 +74,7 @@ func DirInit(preserveOldConfigDir bool) string {
|
|||||||
if isAccessible {
|
if isAccessible {
|
||||||
err = os.RemoveAll(ConfigDir)
|
err = os.RemoveAll(ConfigDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(AnsiError+"Failed to remove existing config directory:", err.Error()+AnsiReset)
|
PrintError("Failed to remove existing config directory: "+err.Error(), ErrorWrite, true)
|
||||||
os.Exit(ErrorWrite)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,8 +82,7 @@ func DirInit(preserveOldConfigDir bool) string {
|
|||||||
// create config directory w/devices subdirectory
|
// create config directory w/devices subdirectory
|
||||||
err = os.MkdirAll(ConfigDir+PathSeparator+"devices", 0700)
|
err = os.MkdirAll(ConfigDir+PathSeparator+"devices", 0700)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(AnsiError+"Failed to create \""+ConfigDir+"\":", err.Error()+AnsiReset)
|
PrintError("Failed to create \""+ConfigDir+"\": "+err.Error(), ErrorWrite, true)
|
||||||
os.Exit(ErrorWrite)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return oldDeviceID
|
return oldDeviceID
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
)
|
)
|
||||||
@@ -16,8 +15,7 @@ func LaunchClipClearProcess(copySubject string) {
|
|||||||
WriteToStdin(cmd, copySubject)
|
WriteToStdin(cmd, copySubject)
|
||||||
err := cmd.Start()
|
err := cmd.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(AnsiError + "Failed to launch automated clipboard clearing process - Does this libmutton implementation support the \"clipclear\" argument?" + AnsiReset)
|
PrintError("Failed to launch automated clipboard clearing process - Does this libmutton implementation support the \"clipclear\" argument?", ErrorClipboard, true)
|
||||||
os.Exit(ErrorClipboard)
|
|
||||||
}
|
}
|
||||||
os.Exit(0) // use os.Exit directly since this version of this function is only meant for non-interactive CLI implementations
|
os.Exit(0) // use os.Exit directly since this version of this function is only meant for non-interactive CLI implementations
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -17,8 +16,7 @@ func LaunchClipClearProcess(copySubject string, isWayland bool) {
|
|||||||
WriteToStdin(cmd, copySubject)
|
WriteToStdin(cmd, copySubject)
|
||||||
err := cmd.Start()
|
err := cmd.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(AnsiError + "Failed to launch automated clipboard clearing process - Does this libmutton implementation support the \"clipclear\" argument?" + AnsiReset)
|
PrintError("Failed to launch automated clipboard clearing process - Does this libmutton implementation support the \"clipclear\" argument?", ErrorClipboard, true)
|
||||||
os.Exit(ErrorClipboard)
|
|
||||||
}
|
}
|
||||||
os.Exit(0) // use os.Exit directly since this version of this function is only meant for non-interactive CLI implementations
|
os.Exit(0) // use os.Exit directly since this version of this function is only meant for non-interactive CLI implementations
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-12
@@ -18,21 +18,18 @@ func TargetIsFile(targetLocation string, errorOnFail bool, failCondition uint8)
|
|||||||
targetInfo, err := os.Stat(targetLocation)
|
targetInfo, err := os.Stat(targetLocation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errorOnFail {
|
if errorOnFail {
|
||||||
fmt.Println(AnsiError + "Failed to access \"" + targetLocation + "\" - Ensure it exists and has the correct permissions" + AnsiReset)
|
PrintError("Failed to access \""+targetLocation+"\" - Ensure it exists and has the correct permissions", ErrorTargetNotFound, true)
|
||||||
os.Exit(ErrorTargetNotFound)
|
|
||||||
}
|
}
|
||||||
return false, false
|
return false, false
|
||||||
}
|
}
|
||||||
if targetInfo.IsDir() {
|
if targetInfo.IsDir() {
|
||||||
if errorOnFail && failCondition == 2 {
|
if errorOnFail && failCondition == 2 {
|
||||||
fmt.Println(AnsiError + "\"" + targetLocation + "\" is a directory" + AnsiReset)
|
PrintError("\""+targetLocation+"\" is a directory", ErrorTargetWrongType, true)
|
||||||
os.Exit(ErrorTargetWrongType)
|
|
||||||
}
|
}
|
||||||
return false, true
|
return false, true
|
||||||
} else {
|
} else {
|
||||||
if errorOnFail && failCondition == 1 {
|
if errorOnFail && failCondition == 1 {
|
||||||
fmt.Println(AnsiError + "\"" + targetLocation + "\" is a file" + AnsiReset)
|
PrintError("\""+targetLocation+"\" is a file", ErrorTargetWrongType, true)
|
||||||
os.Exit(ErrorTargetWrongType)
|
|
||||||
}
|
}
|
||||||
return true, true
|
return true, true
|
||||||
}
|
}
|
||||||
@@ -43,8 +40,7 @@ func WriteEntry(targetLocation string, entryData []string) {
|
|||||||
encryptedBytes := EncryptGPG(entryData)
|
encryptedBytes := EncryptGPG(entryData)
|
||||||
err := os.WriteFile(targetLocation, encryptedBytes, 0600)
|
err := os.WriteFile(targetLocation, encryptedBytes, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(AnsiError+"Failed to write to file:", err.Error()+AnsiReset)
|
PrintError("Failed to write to file: "+err.Error(), ErrorWrite, true)
|
||||||
os.Exit(ErrorWrite)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,8 +49,7 @@ func WriteEntry(targetLocation string, entryData []string) {
|
|||||||
func WriteToStdin(cmd *exec.Cmd, input string) {
|
func WriteToStdin(cmd *exec.Cmd, input string) {
|
||||||
stdin, err := cmd.StdinPipe()
|
stdin, err := cmd.StdinPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(AnsiError+"Failed to access stdin for system command:", err.Error()+AnsiReset)
|
PrintError("Failed to access stdin for system command: "+err.Error(), ErrorOther, true)
|
||||||
os.Exit(ErrorOther)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
@@ -69,8 +64,7 @@ func WriteToStdin(cmd *exec.Cmd, input string) {
|
|||||||
func CreateTempFile() *os.File {
|
func CreateTempFile() *os.File {
|
||||||
tempFile, err := os.CreateTemp("", "*.markdown")
|
tempFile, err := os.CreateTemp("", "*.markdown")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(AnsiError+"Failed to create temporary file:", err.Error()+AnsiReset)
|
PrintError("Failed to create temporary file: "+err.Error(), ErrorWrite, true)
|
||||||
os.Exit(ErrorWrite)
|
|
||||||
}
|
}
|
||||||
return tempFile
|
return tempFile
|
||||||
}
|
}
|
||||||
@@ -182,3 +176,16 @@ func EntryIsNotEmpty(entryData []string) bool {
|
|||||||
func ExpandPathWithHome(path string) string {
|
func ExpandPathWithHome(path string) string {
|
||||||
return strings.Replace(path, "~", Home, 1)
|
return strings.Replace(path, "~", Home, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PrintError prints an error message in the standard libmutton format and exits with the specified exit code.
|
||||||
|
// Requires: message (the error message to print),
|
||||||
|
// exitCode (the exit code to use),
|
||||||
|
// forceHardExit (if true, exit immediately; if false, allow soft exit for interactive clients).
|
||||||
|
func PrintError(message string, exitCode int, forceHardExit bool) {
|
||||||
|
fmt.Println(AnsiError + message + AnsiReset)
|
||||||
|
if forceHardExit {
|
||||||
|
os.Exit(exitCode)
|
||||||
|
} else {
|
||||||
|
Exit(exitCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+27
-53
@@ -27,7 +27,7 @@ func GetSSHClient(manualSync bool) (*ssh.Client, string, bool) {
|
|||||||
var sshUserConfig []string
|
var sshUserConfig []string
|
||||||
var missingValueError string
|
var missingValueError string
|
||||||
if manualSync {
|
if manualSync {
|
||||||
missingValueError = core.AnsiError + "SSH settings not fully configured" + core.AnsiReset
|
missingValueError = "SSH settings not fully configured"
|
||||||
} else {
|
} else {
|
||||||
missingValueError = "0" // allow silent exit at this point in offline mode
|
missingValueError = "0" // allow silent exit at this point in offline mode
|
||||||
}
|
}
|
||||||
@@ -53,8 +53,7 @@ func GetSSHClient(manualSync bool) (*ssh.Client, string, bool) {
|
|||||||
case 6:
|
case 6:
|
||||||
isWindows, err = strconv.ParseBool(key)
|
isWindows, err = strconv.ParseBool(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to parse server OS type:", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to parse server OS type: "+err.Error(), core.ErrorRead, true)
|
||||||
os.Exit(core.ErrorRead)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,8 +61,7 @@ func GetSSHClient(manualSync bool) (*ssh.Client, string, bool) {
|
|||||||
// read private key
|
// read private key
|
||||||
key, err := os.ReadFile(keyFile)
|
key, err := os.ReadFile(keyFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to read private key file:", keyFile+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to read private key: "+keyFile, core.ErrorRead, true)
|
||||||
os.Exit(core.ErrorRead)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse private key
|
// parse private key
|
||||||
@@ -74,16 +72,14 @@ func GetSSHClient(manualSync bool) (*ssh.Client, string, bool) {
|
|||||||
parsedKey, err = ssh.ParsePrivateKeyWithPassphrase(key, core.PassphraseInputFunction("Enter passphrase for your SSH keyfile:"))
|
parsedKey, err = ssh.ParsePrivateKeyWithPassphrase(key, core.PassphraseInputFunction("Enter passphrase for your SSH keyfile:"))
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to parse private key:", keyFile+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to parse private key: "+keyFile, core.ErrorRead, true)
|
||||||
os.Exit(core.ErrorRead)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// read known hosts file
|
// read known hosts file
|
||||||
var hostKeyCallback ssh.HostKeyCallback
|
var hostKeyCallback ssh.HostKeyCallback
|
||||||
hostKeyCallback, err = knownhosts.New(core.Home + core.PathSeparator + ".ssh" + core.PathSeparator + "known_hosts")
|
hostKeyCallback, err = knownhosts.New(core.Home + core.PathSeparator + ".ssh" + core.PathSeparator + "known_hosts")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to read known hosts file:", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to read known hosts file: "+err.Error(), core.ErrorRead, true)
|
||||||
os.Exit(core.ErrorRead)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// configure SSH client
|
// configure SSH client
|
||||||
@@ -99,8 +95,7 @@ func GetSSHClient(manualSync bool) (*ssh.Client, string, bool) {
|
|||||||
// connect to SSH server
|
// connect to SSH server
|
||||||
sshClient, err := ssh.Dial("tcp", ip+":"+port, sshConfig)
|
sshClient, err := ssh.Dial("tcp", ip+":"+port, sshConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to connect to remote server:", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to connect to remote server: "+err.Error(), core.ErrorServerConnection, false) // do not crash/close interactive clients
|
||||||
core.Exit(core.ErrorServerConnection) // do not close/crash interactive clients
|
|
||||||
return nil, "", false
|
return nil, "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,8 +107,7 @@ func GetSSHOutput(sshClient *ssh.Client, cmd, stdin string) string {
|
|||||||
// create a session
|
// create a session
|
||||||
sshSession, err := sshClient.NewSession()
|
sshSession, err := sshClient.NewSession()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to establish SSH session:", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to establish SSH session: "+err.Error(), core.ErrorServerConnection, true)
|
||||||
os.Exit(core.ErrorServerConnection)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// provide stdin data for session
|
// provide stdin data for session
|
||||||
@@ -123,8 +117,7 @@ func GetSSHOutput(sshClient *ssh.Client, cmd, stdin string) string {
|
|||||||
var output []byte
|
var output []byte
|
||||||
output, err = sshSession.CombinedOutput(cmd)
|
output, err = sshSession.CombinedOutput(cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to run SSH command:", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to run SSH command: "+err.Error(), core.ErrorSyncProcess, true)
|
||||||
os.Exit(core.ErrorSyncProcess)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert the output to a string and remove leading/trailing whitespace
|
// convert the output to a string and remove leading/trailing whitespace
|
||||||
@@ -140,8 +133,7 @@ func getRemoteDataFromClient(sshClient *ssh.Client, manualSync bool) (map[string
|
|||||||
deviceIDList := core.GenDeviceIDList(true)
|
deviceIDList := core.GenDeviceIDList(true)
|
||||||
if len(*deviceIDList) == 0 {
|
if len(*deviceIDList) == 0 {
|
||||||
if manualSync {
|
if manualSync {
|
||||||
fmt.Println(core.AnsiError + "Sync failed - No device ID found" + core.AnsiReset)
|
core.PrintError("Sync failed - No device ID found", core.ErrorTargetNotFound, true)
|
||||||
os.Exit(core.ErrorTargetNotFound)
|
|
||||||
} else {
|
} else {
|
||||||
core.Exit(0) // exit silently if the sync job was called automatically, as the user may just be in offline mode
|
core.Exit(0) // exit silently if the sync job was called automatically, as the user may just be in offline mode
|
||||||
}
|
}
|
||||||
@@ -154,13 +146,11 @@ func getRemoteDataFromClient(sshClient *ssh.Client, manualSync bool) (map[string
|
|||||||
|
|
||||||
// parse output/re-form lists
|
// parse output/re-form lists
|
||||||
if len(outputSlice) != 5 { // ensure information from server is complete
|
if len(outputSlice) != 5 { // ensure information from server is complete
|
||||||
fmt.Println(core.AnsiError + "Sync failed - Unable to fetch remote data; server returned an unexpected response" + core.AnsiReset)
|
core.PrintError("Sync failed - Unable to fetch remote data; server returned an unexpected response", core.ErrorSyncProcess, true)
|
||||||
os.Exit(core.ErrorSyncProcess)
|
|
||||||
}
|
}
|
||||||
serverTime, err := strconv.ParseInt(outputSlice[0], 10, 64)
|
serverTime, err := strconv.ParseInt(outputSlice[0], 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to parse server time:", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to parse server time: "+err.Error(), core.ErrorRead, true)
|
||||||
os.Exit(core.ErrorRead)
|
|
||||||
}
|
}
|
||||||
entries := strings.Split(outputSlice[1], core.FSMisc)[1:]
|
entries := strings.Split(outputSlice[1], core.FSMisc)[1:]
|
||||||
modsStrings := strings.Split(outputSlice[2], core.FSMisc)[1:]
|
modsStrings := strings.Split(outputSlice[2], core.FSMisc)[1:]
|
||||||
@@ -173,8 +163,7 @@ func getRemoteDataFromClient(sshClient *ssh.Client, manualSync bool) (map[string
|
|||||||
for _, modString := range modsStrings {
|
for _, modString := range modsStrings {
|
||||||
mod, err = strconv.ParseInt(modString, 10, 64)
|
mod, err = strconv.ParseInt(modString, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to parse mod time:", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to parse mod time: "+err.Error(), core.ErrorRead, true)
|
||||||
os.Exit(core.ErrorRead)
|
|
||||||
}
|
}
|
||||||
mods = append(mods, mod)
|
mods = append(mods, mod)
|
||||||
}
|
}
|
||||||
@@ -220,14 +209,12 @@ func sftpSync(sshClient *ssh.Client, sshEntryRoot string, sshIsWindows bool, dow
|
|||||||
// create an SFTP client from sshClient
|
// create an SFTP client from sshClient
|
||||||
sftpClient, err := sftp.NewClient(sshClient)
|
sftpClient, err := sftp.NewClient(sshClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to establish SFTP session:", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to establish SFTP session: "+err.Error(), core.ErrorServerConnection, true)
|
||||||
os.Exit(core.ErrorServerConnection)
|
|
||||||
}
|
}
|
||||||
defer func(sftpClient *sftp.Client) {
|
defer func(sftpClient *sftp.Client) {
|
||||||
err = sftpClient.Close()
|
err = sftpClient.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to close SFTP client:", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to close SFTP client: "+err.Error(), core.ErrorServerConnection, true)
|
||||||
os.Exit(core.ErrorServerConnection)
|
|
||||||
}
|
}
|
||||||
}(sftpClient)
|
}(sftpClient)
|
||||||
|
|
||||||
@@ -245,8 +232,7 @@ func sftpSync(sshClient *ssh.Client, sshEntryRoot string, sshIsWindows bool, dow
|
|||||||
var fileInfo os.FileInfo
|
var fileInfo os.FileInfo
|
||||||
fileInfo, err = sftpClient.Stat(remoteEntryFullPath)
|
fileInfo, err = sftpClient.Stat(remoteEntryFullPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to get remote file info (mod time):", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to get remote file info (mod time): "+err.Error(), core.ErrorRead, true)
|
||||||
os.Exit(core.ErrorRead)
|
|
||||||
}
|
}
|
||||||
modTime := fileInfo.ModTime()
|
modTime := fileInfo.ModTime()
|
||||||
|
|
||||||
@@ -254,8 +240,7 @@ func sftpSync(sshClient *ssh.Client, sshEntryRoot string, sshIsWindows bool, dow
|
|||||||
var remoteFile *sftp.File
|
var remoteFile *sftp.File
|
||||||
remoteFile, err = sftpClient.Open(remoteEntryFullPath)
|
remoteFile, err = sftpClient.Open(remoteEntryFullPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to open remote file:", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to open remote file: "+err.Error(), core.ErrorRead, true)
|
||||||
os.Exit(core.ErrorRead)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// store path to local entry
|
// store path to local entry
|
||||||
@@ -265,15 +250,13 @@ func sftpSync(sshClient *ssh.Client, sshEntryRoot string, sshIsWindows bool, dow
|
|||||||
var localFile *os.File
|
var localFile *os.File
|
||||||
localFile, err = os.OpenFile(localEntryFullPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
|
localFile, err = os.OpenFile(localEntryFullPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to create local file:", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to create local file: "+err.Error(), core.ErrorWrite, true)
|
||||||
os.Exit(core.ErrorWrite)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// download the file
|
// download the file
|
||||||
_, err = remoteFile.WriteTo(localFile)
|
_, err = remoteFile.WriteTo(localFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to download remote file:", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to download remote file: "+err.Error(), core.ErrorSyncProcess, true)
|
||||||
os.Exit(core.ErrorSyncProcess)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// close the files
|
// close the files
|
||||||
@@ -302,8 +285,7 @@ func sftpSync(sshClient *ssh.Client, sshEntryRoot string, sshIsWindows bool, dow
|
|||||||
var fileInfo os.FileInfo
|
var fileInfo os.FileInfo
|
||||||
fileInfo, err = os.Stat(localEntryFullPath)
|
fileInfo, err = os.Stat(localEntryFullPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to get local file info (mod time):", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to get local file info (mod time): "+err.Error(), core.ErrorRead, true)
|
||||||
os.Exit(core.ErrorRead)
|
|
||||||
}
|
}
|
||||||
modTime := fileInfo.ModTime()
|
modTime := fileInfo.ModTime()
|
||||||
|
|
||||||
@@ -311,8 +293,7 @@ func sftpSync(sshClient *ssh.Client, sshEntryRoot string, sshIsWindows bool, dow
|
|||||||
var localFile *os.File
|
var localFile *os.File
|
||||||
localFile, err = os.Open(localEntryFullPath)
|
localFile, err = os.Open(localEntryFullPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to open local file:", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to open local file: "+err.Error(), core.ErrorRead, true)
|
||||||
os.Exit(core.ErrorRead)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// store path to remote entry
|
// store path to remote entry
|
||||||
@@ -322,15 +303,13 @@ func sftpSync(sshClient *ssh.Client, sshEntryRoot string, sshIsWindows bool, dow
|
|||||||
var remoteFile *sftp.File
|
var remoteFile *sftp.File
|
||||||
remoteFile, err = sftpClient.OpenFile(remoteEntryFullPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY)
|
remoteFile, err = sftpClient.OpenFile(remoteEntryFullPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to create remote file ("+remoteEntryFullPath+"):", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to create remote file ("+remoteEntryFullPath+"): "+err.Error(), core.ErrorWrite, true)
|
||||||
os.Exit(core.ErrorWrite)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// upload the file
|
// upload the file
|
||||||
_, err = localFile.WriteTo(remoteFile)
|
_, err = localFile.WriteTo(remoteFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to upload local file:", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to upload local file: "+err.Error(), core.ErrorSyncProcess, true)
|
||||||
os.Exit(core.ErrorSyncProcess)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// close the files
|
// close the files
|
||||||
@@ -340,8 +319,7 @@ func sftpSync(sshClient *ssh.Client, sshEntryRoot string, sshIsWindows bool, dow
|
|||||||
// set permissions on remote file
|
// set permissions on remote file
|
||||||
err = sftpClient.Chmod(remoteEntryFullPath, 0600)
|
err = sftpClient.Chmod(remoteEntryFullPath, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to set permissions on remote file:", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to set permissions on remote file: "+err.Error(), core.ErrorSyncProcess, true)
|
||||||
os.Exit(core.ErrorSyncProcess)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the modification time of the remote file to match the value saved from the local file (from before the upload)
|
// set the modification time of the remote file to match the value saved from the local file (from before the upload)
|
||||||
@@ -410,8 +388,7 @@ func deletionSync(deletions []string) {
|
|||||||
fmt.Println(ansiDelete+deletion+core.AnsiReset, "has been sheared, removing locally (if it exists)")
|
fmt.Println(ansiDelete+deletion+core.AnsiReset, "has been sheared, removing locally (if it exists)")
|
||||||
err := os.RemoveAll(core.TargetLocationFormat(deletion))
|
err := os.RemoveAll(core.TargetLocationFormat(deletion))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Failed to shear "+deletion+" locally:", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Failed to shear "+deletion+" locally: "+err.Error(), core.ErrorWrite, true)
|
||||||
os.Exit(core.ErrorWrite)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -432,12 +409,10 @@ func folderSync(folders []string) {
|
|||||||
if !isFile && !isAccessible {
|
if !isFile && !isAccessible {
|
||||||
err := os.MkdirAll(folderFullPath, 0700)
|
err := os.MkdirAll(folderFullPath, 0700)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Failed to create folder \""+folder+"\":", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Failed to create folder ("+folder+"): "+err.Error(), core.ErrorWrite, true)
|
||||||
os.Exit(core.ErrorWrite)
|
|
||||||
}
|
}
|
||||||
} else if isFile {
|
} else if isFile {
|
||||||
fmt.Println(core.AnsiError + "Sync failed - Failed to create folder \"" + folder + "\" - A file with the same name already exists" + core.AnsiReset)
|
core.PrintError("Sync failed - Failed to create folder ("+folder+") - A file with the same name already exists", core.ErrorTargetExists, true)
|
||||||
os.Exit(core.ErrorTargetExists)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -454,8 +429,7 @@ func RunJob(manualSync, returnLists bool) [3][]string {
|
|||||||
defer func(sshClient *ssh.Client) {
|
defer func(sshClient *ssh.Client) {
|
||||||
err := sshClient.Close()
|
err := sshClient.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to close SSH client:", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to close SSH client: "+err.Error(), core.ErrorServerConnection, true)
|
||||||
os.Exit(core.ErrorServerConnection)
|
|
||||||
}
|
}
|
||||||
}(sshClient)
|
}(sshClient)
|
||||||
|
|
||||||
|
|||||||
+5
-11
@@ -1,7 +1,6 @@
|
|||||||
package sync
|
package sync
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -56,8 +55,7 @@ func ShearLocal(targetLocationIncomplete, clientDeviceID string) (string, bool)
|
|||||||
}
|
}
|
||||||
err := os.RemoveAll(targetLocationComplete)
|
err := os.RemoveAll(targetLocationComplete)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Failed to remove local target:", err.Error()+core.AnsiReset)
|
core.PrintError("Failed to remove local target: "+err.Error(), core.ErrorWrite, true)
|
||||||
os.Exit(core.ErrorWrite)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !onServer && len(*deviceIDList) > 0 { // return the device ID if running on the client and a device ID exists (online mode)
|
if !onServer && len(*deviceIDList) > 0 { // return the device ID if running on the client and a device ID exists (online mode)
|
||||||
@@ -82,15 +80,13 @@ func RenameLocal(oldLocationIncomplete, newLocationIncomplete string, verifyOldL
|
|||||||
// ensure newLocation does not exist
|
// ensure newLocation does not exist
|
||||||
_, isAccessible := core.TargetIsFile(newLocation, false, 0)
|
_, isAccessible := core.TargetIsFile(newLocation, false, 0)
|
||||||
if isAccessible {
|
if isAccessible {
|
||||||
fmt.Println(core.AnsiError + "\"" + newLocation + "\" already exists" + core.AnsiReset)
|
core.PrintError("\""+newLocation+"\" already exists", core.ErrorTargetExists, true)
|
||||||
os.Exit(core.ErrorTargetExists)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// rename oldLocation to newLocation
|
// rename oldLocation to newLocation
|
||||||
err := os.Rename(oldLocation, newLocation)
|
err := os.Rename(oldLocation, newLocation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError + "Failed to rename - Does the target containing directory exist?" + core.AnsiReset)
|
core.PrintError("Failed to rename - Does the target containing directory exist?", core.ErrorTargetNotFound, true)
|
||||||
os.Exit(core.ErrorTargetNotFound)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not exit program, as this function is used as part of RenameRemoteFromClient
|
// do not exit program, as this function is used as part of RenameRemoteFromClient
|
||||||
@@ -104,11 +100,9 @@ func AddFolderLocal(targetLocationIncomplete string) {
|
|||||||
err := os.Mkdir(targetLocationComplete, 0700)
|
err := os.Mkdir(targetLocationComplete, 0700)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsExist(err) {
|
if os.IsExist(err) {
|
||||||
fmt.Println(core.AnsiError + "Directory already exists" + core.AnsiReset)
|
core.PrintError("Directory already exists", core.ErrorTargetExists, true)
|
||||||
os.Exit(core.ErrorTargetExists)
|
|
||||||
} else {
|
} else {
|
||||||
fmt.Println(core.AnsiError+"Failed to create directory:", err.Error()+core.AnsiReset)
|
core.PrintError("Failed to create directory: "+err.Error(), core.ErrorWrite, true)
|
||||||
os.Exit(core.ErrorWrite)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-5
@@ -3,7 +3,6 @@
|
|||||||
package sync
|
package sync
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -25,12 +24,10 @@ func WalkEntryDir() ([]string, []string) {
|
|||||||
// check for errors encountered while walking directory
|
// check for errors encountered while walking directory
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
fmt.Println(core.AnsiError + "The entry directory does not exist - Initialize libmutton to create it" + core.AnsiReset)
|
core.PrintError("The entry directory does not exist - Initialize libmutton to create it", core.ErrorOther, true)
|
||||||
} else {
|
} else {
|
||||||
// otherwise, print the source of the error
|
core.PrintError("An unexpected error occurred while generating the entry list: "+err.Error(), core.ErrorOther, true)
|
||||||
fmt.Println(core.AnsiError+"An unexpected error occurred while generating the entry list:", err.Error()+core.AnsiReset)
|
|
||||||
}
|
}
|
||||||
os.Exit(core.ErrorOther)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// trim root path from each path before storing
|
// trim root path from each path before storing
|
||||||
|
|||||||
+2
-5
@@ -3,7 +3,6 @@
|
|||||||
package sync
|
package sync
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -26,12 +25,10 @@ func WalkEntryDir() ([]string, []string) {
|
|||||||
// check for errors encountered while walking directory
|
// check for errors encountered while walking directory
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
fmt.Println(core.AnsiError + "The entry directory does not exist - Initialize libmutton to create it" + core.AnsiReset)
|
core.PrintError("The entry directory does not exist - Initialize libmutton to create it", core.ErrorOther, true)
|
||||||
} else {
|
} else {
|
||||||
// otherwise, print the source of the error
|
core.PrintError("An unexpected error occurred while generating the entry list: "+err.Error(), core.ErrorOther, true)
|
||||||
fmt.Println(core.AnsiError+"An unexpected error occurred while generating the entry list:", err.Error()+core.AnsiReset)
|
|
||||||
}
|
}
|
||||||
os.Exit(core.ErrorOther)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// trim root path from each path before storing and replace backslashes with forward slashes
|
// trim root path from each path before storing and replace backslashes with forward slashes
|
||||||
|
|||||||
+3
-7
@@ -1,7 +1,6 @@
|
|||||||
package sync
|
package sync
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -24,8 +23,7 @@ func DeviceIDGen(oldDeviceID string) (string, string) {
|
|||||||
// create new device ID file (locally)
|
// create new device ID file (locally)
|
||||||
fileToClose, err := os.OpenFile(core.ConfigDir+core.PathSeparator+"devices"+core.PathSeparator+newDeviceID, os.O_CREATE|os.O_WRONLY, 0600)
|
fileToClose, err := os.OpenFile(core.ConfigDir+core.PathSeparator+"devices"+core.PathSeparator+newDeviceID, os.O_CREATE|os.O_WRONLY, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Failed to create local device ID file:", err.Error()+core.AnsiReset)
|
core.PrintError("Failed to create local device ID file: "+err.Error(), core.ErrorWrite, true)
|
||||||
os.Exit(core.ErrorWrite)
|
|
||||||
}
|
}
|
||||||
_ = fileToClose.Close() // error ignored; if the file could be created, it can probably be closed
|
_ = fileToClose.Close() // error ignored; if the file could be created, it can probably be closed
|
||||||
|
|
||||||
@@ -36,15 +34,13 @@ func DeviceIDGen(oldDeviceID string) (string, string) {
|
|||||||
sshEntryRootSSHIsWindows := strings.Split(GetSSHOutput(sshClient, "libmuttonserver register", newDeviceID+"\n"+oldDeviceID), core.FSSpace)
|
sshEntryRootSSHIsWindows := strings.Split(GetSSHOutput(sshClient, "libmuttonserver register", newDeviceID+"\n"+oldDeviceID), core.FSSpace)
|
||||||
err = sshClient.Close()
|
err = sshClient.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Init failed - Unable to close SSH client:", err.Error()+core.AnsiReset)
|
core.PrintError("Init failed - Unable to close SSH client: "+err.Error(), core.ErrorServerConnection, true)
|
||||||
os.Exit(core.ErrorServerConnection)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove old device ID file (locally; may not exist)
|
// remove old device ID file (locally; may not exist)
|
||||||
err = os.RemoveAll(core.ConfigDir + core.PathSeparator + "devices" + core.PathSeparator + oldDeviceID)
|
err = os.RemoveAll(core.ConfigDir + core.PathSeparator + "devices" + core.PathSeparator + oldDeviceID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Failed to remove old device ID file (locally):", err.Error()+core.AnsiReset)
|
core.PrintError("Failed to remove old device ID file (locally): "+err.Error(), core.ErrorWrite, true)
|
||||||
os.Exit(core.ErrorWrite)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sshEntryRootSSHIsWindows[0], sshEntryRootSSHIsWindows[1]
|
return sshEntryRootSSHIsWindows[0], sshEntryRootSSHIsWindows[1]
|
||||||
|
|||||||
+3
-8
@@ -1,8 +1,6 @@
|
|||||||
package sync
|
package sync
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/rwinkhart/libmutton/core"
|
"github.com/rwinkhart/libmutton/core"
|
||||||
@@ -28,8 +26,7 @@ func ShearRemoteFromClient(targetLocationIncomplete string, forceOffline bool) {
|
|||||||
// close the SSH client
|
// close the SSH client
|
||||||
err := sshClient.Close()
|
err := sshClient.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to close SSH client:", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to close SSH client: "+err.Error(), core.ErrorServerConnection, true)
|
||||||
os.Exit(core.ErrorServerConnection)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,8 +52,7 @@ func RenameRemoteFromClient(oldLocationIncomplete, newLocationIncomplete string,
|
|||||||
// close the SSH client
|
// close the SSH client
|
||||||
err := sshClient.Close()
|
err := sshClient.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to close SSH client:", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to close SSH client: "+err.Error(), core.ErrorServerConnection, true)
|
||||||
os.Exit(core.ErrorServerConnection)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,8 +75,7 @@ func AddFolderRemoteFromClient(targetLocationIncomplete string, forceOffline boo
|
|||||||
// close the SSH client
|
// close the SSH client
|
||||||
err := sshClient.Close()
|
err := sshClient.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Sync failed - Unable to close SSH client:", err.Error()+core.AnsiReset)
|
core.PrintError("Sync failed - Unable to close SSH client: "+err.Error(), core.ErrorServerConnection, true)
|
||||||
os.Exit(core.ErrorServerConnection)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -17,8 +17,7 @@ func GetRemoteDataFromServer(clientDeviceID string) {
|
|||||||
modList := getModTimes(entryList)
|
modList := getModTimes(entryList)
|
||||||
deletionsList, err := os.ReadDir(core.ConfigDir + core.PathSeparator + "deletions")
|
deletionsList, err := os.ReadDir(core.ConfigDir + core.PathSeparator + "deletions")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError+"Failed to read the deletions directory:", err.Error()+core.AnsiReset)
|
core.PrintError("Failed to read the deletions directory: "+err.Error(), core.ErrorRead, true)
|
||||||
os.Exit(core.ErrorRead)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// print the current UNIX timestamp to stdout
|
// print the current UNIX timestamp to stdout
|
||||||
|
|||||||
Reference in New Issue
Block a user