mirror of
https://github.com/rwinkhart/libmutton.git
synced 2026-08-28 04:46:42 -04:00
Create all config/entry files (both local and remote) with 0600 permissions
This commit is contained in:
@@ -15,7 +15,7 @@ See the [developer guide](https://github.com/rwinkhart/libmutton/blob/main/wiki/
|
||||
#### Release v0.2.1
|
||||
- [x] Only run getSSHClient once to prevent being asked for keyfile password multiple times
|
||||
- [x] After this, handle all errors in sync/client.go
|
||||
- [ ] Ensure all config files and entry files are created with 0600 permissions
|
||||
- [x] Ensure all config files and entry files are created with 0600 permissions
|
||||
- [x] Add error-specific exit codes
|
||||
- [x] Split into separate repos
|
||||
1. libmutton: backend package (rename to core), sync package, libmuttonserver
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
func loadConfig() *ini.File {
|
||||
cfg, err := ini.Load(ConfigPath)
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to load libmutton.ini: " + err.Error() + AnsiReset)
|
||||
fmt.Println(AnsiError+"Failed to load libmutton.ini:", err.Error()+AnsiReset)
|
||||
os.Exit(101)
|
||||
}
|
||||
return cfg
|
||||
@@ -56,7 +56,7 @@ 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)
|
||||
fmt.Println(AnsiError+"Failed to read the devices directory:", err.Error()+AnsiReset)
|
||||
os.Exit(101)
|
||||
}
|
||||
return &deviceIDList
|
||||
@@ -93,7 +93,7 @@ func WriteConfig(valuesToWrite [][3]string, append bool) {
|
||||
// save to libmutton.ini
|
||||
err := cfg.SaveTo(ConfigPath)
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to save libmutton.ini: " + err.Error() + AnsiReset)
|
||||
fmt.Println(AnsiError+"Failed to save libmutton.ini:", err.Error()+AnsiReset)
|
||||
os.Exit(102)
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -16,7 +16,7 @@ func copyField(executableName, copySubject string) {
|
||||
writeToStdin(cmd, copySubject)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to copy to clipboard: " + err.Error() + AnsiReset)
|
||||
fmt.Println(AnsiError+"Failed to copy to clipboard:", err.Error()+AnsiReset)
|
||||
os.Exit(110)
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ func clipClear(oldContents string) {
|
||||
cmd := exec.Command("pbpaste")
|
||||
newContents, err := cmd.Output()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to read clipboard contents: " + err.Error() + AnsiReset)
|
||||
fmt.Println(AnsiError+"Failed to read clipboard contents:", err.Error()+AnsiReset)
|
||||
os.Exit(110)
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ func clipClear(oldContents string) {
|
||||
writeToStdin(cmd, "")
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to clear clipboard: " + err.Error() + AnsiReset)
|
||||
fmt.Println(AnsiError+"Failed to clear clipboard:", err.Error()+AnsiReset)
|
||||
os.Exit(110)
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -16,7 +16,7 @@ func copyField(executableName, copySubject string) {
|
||||
writeToStdin(cmd, copySubject)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to copy to clipboard: " + err.Error() + AnsiReset)
|
||||
fmt.Println(AnsiError+"Failed to copy to clipboard:", err.Error()+AnsiReset)
|
||||
os.Exit(110)
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ func clipClear(oldContents string) {
|
||||
cmd := exec.Command("termux-clipboard-get")
|
||||
newContents, err := cmd.Output()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to read clipboard contents: " + err.Error() + AnsiReset)
|
||||
fmt.Println(AnsiError+"Failed to read clipboard contents:", err.Error()+AnsiReset)
|
||||
os.Exit(110)
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ func clipClear(oldContents string) {
|
||||
writeToStdin(cmd, "")
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to clear clipboard: " + err.Error() + AnsiReset)
|
||||
fmt.Println(AnsiError+"Failed to clear clipboard:", err.Error()+AnsiReset)
|
||||
os.Exit(110)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ func copyField(executableName, copySubject string) {
|
||||
writeToStdin(cmd, copySubject)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to copy to clipboard: " + err.Error() + AnsiReset)
|
||||
fmt.Println(AnsiError+"Failed to copy to clipboard:", err.Error()+AnsiReset)
|
||||
os.Exit(110)
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ func clipClear(oldContents string) {
|
||||
// read current clipboard contents
|
||||
newContents, err := cmdPaste.Output()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to read clipboard contents: " + err.Error() + AnsiReset)
|
||||
fmt.Println(AnsiError+"Failed to read clipboard contents:", err.Error()+AnsiReset)
|
||||
os.Exit(110)
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ func clipClear(oldContents string) {
|
||||
if oldContents == strings.TrimRight(string(newContents), "\r\n") {
|
||||
err = cmdClear.Run()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to clear clipboard: " + err.Error() + AnsiReset)
|
||||
fmt.Println(AnsiError+"Failed to clear clipboard:", err.Error()+AnsiReset)
|
||||
os.Exit(110)
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -15,7 +15,7 @@ func copyField(executableName, copySubject string) {
|
||||
cmd := exec.Command("powershell.exe", "-c", fmt.Sprintf("echo '%s' | Set-Clipboard", strings.ReplaceAll(copySubject, "'", "''")))
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to copy to clipboard: " + err.Error() + AnsiReset)
|
||||
fmt.Println(AnsiError+"Failed to copy to clipboard:", err.Error()+AnsiReset)
|
||||
os.Exit(110)
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ func clipClear(oldContents string) {
|
||||
cmd := exec.Command("powershell.exe", "-c", "Get-Clipboard")
|
||||
newContents, err := cmd.Output()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to read clipboard contents: " + err.Error() + AnsiReset)
|
||||
fmt.Println(AnsiError+"Failed to read clipboard contents:", err.Error()+AnsiReset)
|
||||
os.Exit(110)
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ func clipClear(oldContents string) {
|
||||
cmd = exec.Command("powershell.exe", "-c", "Set-Clipboard")
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to clear clipboard: " + err.Error() + AnsiReset)
|
||||
fmt.Println(AnsiError+"Failed to clear clipboard:", err.Error()+AnsiReset)
|
||||
os.Exit(110)
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -45,7 +45,7 @@ func GpgKeyGen() string {
|
||||
cmd.Stdin = os.Stdin
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to generate GPG key: " + err.Error() + AnsiReset)
|
||||
fmt.Println(AnsiError+"Failed to generate GPG key:", err.Error()+AnsiReset)
|
||||
os.Exit(111)
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ func DirInit(preserveOldConfigDir bool) string {
|
||||
// create EntryRoot
|
||||
err := os.MkdirAll(EntryRoot, 0700)
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to create \"" + EntryRoot + "\": " + err.Error() + AnsiReset)
|
||||
fmt.Println(AnsiError+"Failed to create \""+EntryRoot+"\":", err.Error()+AnsiReset)
|
||||
os.Exit(102)
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ func DirInit(preserveOldConfigDir bool) string {
|
||||
if isAccessible {
|
||||
err = os.RemoveAll(ConfigDir)
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to remove existing config directory: " + err.Error() + AnsiReset)
|
||||
fmt.Println(AnsiError+"Failed to remove existing config directory:", err.Error()+AnsiReset)
|
||||
os.Exit(102)
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,7 @@ func DirInit(preserveOldConfigDir bool) string {
|
||||
// create config directory w/devices subdirectory
|
||||
err = os.MkdirAll(ConfigDir+PathSeparator+"devices", 0700)
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to create \"" + ConfigDir + "\": " + err.Error() + AnsiReset)
|
||||
fmt.Println(AnsiError+"Failed to create \""+ConfigDir+"\":", err.Error()+AnsiReset)
|
||||
os.Exit(102)
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ func WriteEntry(targetLocation string, entryData []string, verifyEntryDoesNotExi
|
||||
encryptedBytes := EncryptGPG(entryData)
|
||||
err := os.WriteFile(targetLocation, encryptedBytes, 0600)
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to write to file: " + err.Error() + AnsiReset)
|
||||
fmt.Println(AnsiError+"Failed to write to file:", err.Error()+AnsiReset)
|
||||
os.Exit(102)
|
||||
}
|
||||
}
|
||||
@@ -61,7 +61,7 @@ func WriteEntry(targetLocation string, entryData []string, verifyEntryDoesNotExi
|
||||
func writeToStdin(cmd *exec.Cmd, input string) {
|
||||
stdin, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to access stdin for system command: " + err.Error() + AnsiReset)
|
||||
fmt.Println(AnsiError+"Failed to access stdin for system command:", err.Error()+AnsiReset)
|
||||
os.Exit(111)
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ func writeToStdin(cmd *exec.Cmd, input string) {
|
||||
func CreateTempFile() *os.File {
|
||||
tempFile, err := os.CreateTemp("", "*.markdown")
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to create temporary file: " + err.Error() + AnsiReset)
|
||||
fmt.Println(AnsiError+"Failed to create temporary file:", err.Error()+AnsiReset)
|
||||
os.Exit(102)
|
||||
}
|
||||
return tempFile
|
||||
|
||||
+2
-1
@@ -57,7 +57,8 @@ func main() {
|
||||
// register a new device ID
|
||||
// stdin[0] is expected to be the device ID
|
||||
// stdin[1] is expected to be the old device ID (for removal)
|
||||
_, _ = os.Create(core.ConfigDir + core.PathSeparator + "devices" + core.PathSeparator + stdin[0]) // 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, _ := 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])
|
||||
// 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))
|
||||
|
||||
+17
-10
@@ -53,7 +53,7 @@ func GetSSHClient(manualSync bool) (*ssh.Client, string, bool) {
|
||||
case 6:
|
||||
isWindows, err = strconv.ParseBool(key)
|
||||
if err != nil {
|
||||
fmt.Println(core.AnsiError + "Sync failed - Unable to parse server OS type: " + err.Error() + core.AnsiReset)
|
||||
fmt.Println(core.AnsiError+"Sync failed - Unable to parse server OS type:", err.Error()+core.AnsiReset)
|
||||
os.Exit(101)
|
||||
}
|
||||
}
|
||||
@@ -82,7 +82,7 @@ func GetSSHClient(manualSync bool) (*ssh.Client, string, bool) {
|
||||
var hostKeyCallback ssh.HostKeyCallback
|
||||
hostKeyCallback, err = knownhosts.New(core.Home + core.PathSeparator + ".ssh" + core.PathSeparator + "known_hosts")
|
||||
if err != nil {
|
||||
fmt.Println(core.AnsiError + "Sync failed - Unable to read known hosts file: " + err.Error() + core.AnsiReset)
|
||||
fmt.Println(core.AnsiError+"Sync failed - Unable to read known hosts file:", err.Error()+core.AnsiReset)
|
||||
os.Exit(101)
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ func getRemoteDataFromClient(sshClient *ssh.Client, manualSync bool) (map[string
|
||||
}
|
||||
serverTime, err := strconv.ParseInt(outputSlice[0], 10, 64)
|
||||
if err != nil {
|
||||
fmt.Println(core.AnsiError+"Sync failed - Unable to parse server time: ", err.Error()+core.AnsiReset)
|
||||
fmt.Println(core.AnsiError+"Sync failed - Unable to parse server time:", err.Error()+core.AnsiReset)
|
||||
os.Exit(101)
|
||||
}
|
||||
entries := strings.Split(outputSlice[1], FSMisc)[1:]
|
||||
@@ -171,7 +171,7 @@ func getRemoteDataFromClient(sshClient *ssh.Client, manualSync bool) (map[string
|
||||
for _, modString := range modsStrings {
|
||||
mod, err = strconv.ParseInt(modString, 10, 64)
|
||||
if err != nil {
|
||||
fmt.Println(core.AnsiError+"Sync failed - Unable to parse mod time: ", err.Error()+core.AnsiReset)
|
||||
fmt.Println(core.AnsiError+"Sync failed - Unable to parse mod time:", err.Error()+core.AnsiReset)
|
||||
os.Exit(101)
|
||||
}
|
||||
mods = append(mods, mod)
|
||||
@@ -224,7 +224,7 @@ func sftpSync(sshClient *ssh.Client, sshEntryRoot string, sshIsWindows bool, dow
|
||||
defer func(sftpClient *sftp.Client) {
|
||||
err = sftpClient.Close()
|
||||
if err != nil {
|
||||
fmt.Println(core.AnsiError+"Sync failed - Unable to close SFTP client: ", err.Error()+core.AnsiReset)
|
||||
fmt.Println(core.AnsiError+"Sync failed - Unable to close SFTP client:", err.Error()+core.AnsiReset)
|
||||
os.Exit(104)
|
||||
}
|
||||
}(sftpClient)
|
||||
@@ -261,7 +261,7 @@ func sftpSync(sshClient *ssh.Client, sshEntryRoot string, sshIsWindows bool, dow
|
||||
|
||||
// create local file
|
||||
var localFile *os.File
|
||||
localFile, err = os.Create(localEntryFullPath)
|
||||
localFile, err = os.OpenFile(localEntryFullPath, os.O_CREATE|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
fmt.Println(core.AnsiError+"Sync failed - Unable to create local file:", err.Error()+core.AnsiReset)
|
||||
os.Exit(102)
|
||||
@@ -318,7 +318,7 @@ func sftpSync(sshClient *ssh.Client, sshEntryRoot string, sshIsWindows bool, dow
|
||||
|
||||
// create remote file
|
||||
var remoteFile *sftp.File
|
||||
remoteFile, err = sftpClient.Create(remoteEntryFullPath)
|
||||
remoteFile, err = sftpClient.OpenFile(remoteEntryFullPath, os.O_CREATE|os.O_WRONLY)
|
||||
if err != nil {
|
||||
fmt.Println(core.AnsiError+"Sync failed - Unable to create remote file ("+remoteEntryFullPath+"):", err.Error()+core.AnsiReset)
|
||||
os.Exit(102)
|
||||
@@ -335,6 +335,13 @@ func sftpSync(sshClient *ssh.Client, sshEntryRoot string, sshIsWindows bool, dow
|
||||
_ = localFile.Close() // errors ignored; if the files could be opened/created, it can probably be closed
|
||||
_ = remoteFile.Close()
|
||||
|
||||
// set permissions on remote file
|
||||
err = sftpClient.Chmod(remoteEntryFullPath, 0600)
|
||||
if err != nil {
|
||||
fmt.Println(core.AnsiError+"Sync failed - Unable to set permissions on remote file:", err.Error()+core.AnsiReset)
|
||||
os.Exit(103)
|
||||
}
|
||||
|
||||
// set the modification time of the remote file to match the value saved from the local file (from before the upload)
|
||||
err = sftpClient.Chtimes(remoteEntryFullPath, time.Now(), modTime)
|
||||
}
|
||||
@@ -396,7 +403,7 @@ func deletionSync(deletions []string) {
|
||||
fmt.Println(ansiDelete+deletion+core.AnsiReset, "has been sheared, removing locally (if it exists)")
|
||||
err := os.RemoveAll(core.TargetLocationFormat(deletion))
|
||||
if err != nil {
|
||||
fmt.Println(core.AnsiError + "Sync failed - Failed to shear " + deletion + " locally: " + err.Error() + core.AnsiReset)
|
||||
fmt.Println(core.AnsiError+"Sync failed - Failed to shear "+deletion+" locally:", err.Error()+core.AnsiReset)
|
||||
os.Exit(102)
|
||||
}
|
||||
}
|
||||
@@ -457,7 +464,7 @@ func folderSync(folders []string) {
|
||||
if !isFile && !isAccessible {
|
||||
err := os.MkdirAll(folderFullPath, 0700)
|
||||
if err != nil {
|
||||
fmt.Println(core.AnsiError + "Sync failed - Failed to create folder \"" + folder + "\": " + err.Error() + core.AnsiReset)
|
||||
fmt.Println(core.AnsiError+"Sync failed - Failed to create folder \""+folder+"\":", err.Error()+core.AnsiReset)
|
||||
os.Exit(102)
|
||||
}
|
||||
} else if isFile {
|
||||
@@ -475,7 +482,7 @@ func RunJob(manualSync bool) {
|
||||
defer func(sshClient *ssh.Client) {
|
||||
err := sshClient.Close()
|
||||
if err != nil {
|
||||
fmt.Println(core.AnsiError+"Sync failed - Unable to close SSH client: ", err.Error()+core.AnsiReset)
|
||||
fmt.Println(core.AnsiError+"Sync failed - Unable to close SSH client:", err.Error()+core.AnsiReset)
|
||||
os.Exit(104)
|
||||
}
|
||||
}(sshClient)
|
||||
|
||||
+4
-3
@@ -36,12 +36,13 @@ func ShearLocal(targetLocationIncomplete, clientDeviceID string) string {
|
||||
if onServer {
|
||||
for _, device := range *deviceIDList {
|
||||
if device.Name() != clientDeviceID {
|
||||
_, err := os.Create(core.ConfigDir + core.PathSeparator + "deletions" + core.PathSeparator + device.Name() + FSSpace + strings.ReplaceAll(targetLocationIncomplete, "/", FSPath))
|
||||
fileToClose, err := os.OpenFile(core.ConfigDir+core.PathSeparator+"deletions"+core.PathSeparator+device.Name()+FSSpace+strings.ReplaceAll(targetLocationIncomplete, "/", FSPath), os.O_CREATE|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
// do not print error as there is currently no way of seeing server-side errors
|
||||
// failure to add the target to the deletions list will exit the program and result in a client re-uploading the target (non-critical)
|
||||
os.Exit(102)
|
||||
}
|
||||
_ = fileToClose.Close() // error ignored; if the file could be created, it can probably be closed
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,7 +54,7 @@ func ShearLocal(targetLocationIncomplete, clientDeviceID string) string {
|
||||
}
|
||||
err := os.RemoveAll(targetLocationComplete)
|
||||
if err != nil {
|
||||
fmt.Println(core.AnsiError + "Failed to remove local target: " + err.Error() + core.AnsiReset)
|
||||
fmt.Println(core.AnsiError+"Failed to remove local target:", err.Error()+core.AnsiReset)
|
||||
os.Exit(102)
|
||||
}
|
||||
|
||||
@@ -103,7 +104,7 @@ func AddFolderLocal(targetLocationIncomplete string) {
|
||||
fmt.Println(core.AnsiError + "Directory already exists" + core.AnsiReset)
|
||||
os.Exit(106)
|
||||
} else {
|
||||
fmt.Println(core.AnsiError + "Failed to create directory: " + err.Error() + core.AnsiReset)
|
||||
fmt.Println(core.AnsiError+"Failed to create directory:", err.Error()+core.AnsiReset)
|
||||
os.Exit(102)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ func WalkEntryDir() ([]string, []string) {
|
||||
fmt.Println(core.AnsiError+"The entry directory does not exist - Run \""+os.Args[0], "init"+"\" to create it"+core.AnsiReset)
|
||||
} else {
|
||||
// otherwise, print the source of the error
|
||||
fmt.Println(core.AnsiError + "An unexpected error occurred while generating the entry list: " + err.Error() + core.AnsiReset)
|
||||
fmt.Println(core.AnsiError+"An unexpected error occurred while generating the entry list:", err.Error()+core.AnsiReset)
|
||||
}
|
||||
os.Exit(111)
|
||||
}
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ func WalkEntryDir() ([]string, []string) {
|
||||
fmt.Println(joinErrorWithEXE("The entry directory does not exist - Run \"", " init"+"\" to create it"))
|
||||
} else {
|
||||
// otherwise, print the source of the error
|
||||
fmt.Println(core.AnsiError + "An unexpected error occurred while generating the entry list: " + err.Error() + core.AnsiReset)
|
||||
fmt.Println(core.AnsiError+"An unexpected error occurred while generating the entry list:", err.Error()+core.AnsiReset)
|
||||
}
|
||||
os.Exit(111)
|
||||
}
|
||||
|
||||
+11
-3
@@ -23,11 +23,12 @@ func DeviceIDGen(oldDeviceID string) (string, string) {
|
||||
newDeviceID := deviceIDPrefix + "-" + deviceIDSuffix
|
||||
|
||||
// create new device ID file (locally)
|
||||
_, err := os.Create(core.ConfigDir + core.PathSeparator + "devices" + core.PathSeparator + newDeviceID) // TODO remove existing device ID file if it exists (from both client and server)
|
||||
fileToClose, err := os.OpenFile(core.ConfigDir+core.PathSeparator+"devices"+core.PathSeparator+newDeviceID, os.O_CREATE|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
fmt.Println(core.AnsiError + "Failed to create local device ID file: " + err.Error() + core.AnsiReset)
|
||||
fmt.Println(core.AnsiError+"Failed to create local device ID file:", err.Error()+core.AnsiReset)
|
||||
os.Exit(102)
|
||||
}
|
||||
_ = fileToClose.Close() // error ignored; if the file could be created, it can probably be closed
|
||||
|
||||
// register new device ID with server and fetch remote EntryRoot and OS type
|
||||
// also removes the old device ID file (remotely)
|
||||
@@ -36,11 +37,18 @@ func DeviceIDGen(oldDeviceID string) (string, string) {
|
||||
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)
|
||||
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)
|
||||
|
||||
// remove old device ID file (locally; may not exist)
|
||||
err = os.RemoveAll(core.ConfigDir + core.PathSeparator + "devices" + core.PathSeparator + oldDeviceID)
|
||||
if err != nil {
|
||||
fmt.Println(core.AnsiError+"Failed to remove old device ID file (locally):", err.Error()+core.AnsiReset)
|
||||
os.Exit(102)
|
||||
}
|
||||
|
||||
return sshEntryRootSSHIsWindows[0], sshEntryRootSSHIsWindows[1]
|
||||
}
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ func GetRemoteDataFromServer(clientDeviceID string) {
|
||||
modList := getModTimes(entryList)
|
||||
deletionsList, err := os.ReadDir(core.ConfigDir + core.PathSeparator + "deletions")
|
||||
if err != nil {
|
||||
fmt.Println(core.AnsiError + "Failed to read the deletions directory: " + err.Error() + core.AnsiReset)
|
||||
fmt.Println(core.AnsiError+"Failed to read the deletions directory:", err.Error()+core.AnsiReset)
|
||||
os.Exit(101)
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
## Known Bugs - libmutton
|
||||
- On Windows, GPG is sometimes (seems unpredictable) incredibly slow to start (often after a reboot), leading to many operations seemingly hanging
|
||||
- **This will be addressed** in the migration off of GPG that will take place before v1.0.0
|
||||
- If a client is reconfigured to use a new device ID, the old one will remain present on the server. This will not cause any immediate issues, however it will lead to the server creating unnecessary deletions files for the old device ID. Currently, it is recommended to manually delete the old device ID from the server's "devices" directory.
|
||||
- **This will be addressed** in v0.2.1
|
||||
- ~~If a client is reconfigured to use a new device ID, the old one will remain present on the server. This will not cause any immediate issues, however it will lead to the server creating unnecessary deletions files for the old device ID. Currently, it is recommended to manually delete the old device ID from the server's "devices" directory.~~
|
||||
- **Addressed** for v0.2.1
|
||||
- ~~Using a password-protected SSH identity file will prompt for the key's password multiple times when syncing~~
|
||||
- **Addressed** for v0.2.1
|
||||
- Password-protected SSH identity files currently only prompt for password entry in the CLI, and thus they are not yet supported in GUI/TUI implementations
|
||||
|
||||
Reference in New Issue
Block a user