Fix Windows sync (WalkEntryDir now returns only UNIX-style separators); fix setting remote mod time on remote files when downloading; fix server binary compilation; fix init failing silently during SSH configuration

This commit is contained in:
2024-05-31 01:23:50 -04:00
parent b4f0a4e896
commit 50f514ece4
13 changed files with 114 additions and 105 deletions
+1 -1
View File
@@ -35,7 +35,7 @@ func main() {
fmt.Print(backend.EntryRoot + "\x1d" + strconv.FormatBool(backend.IsWindows))
case "init":
// create the necessary directories for libmuttonserver to function
backend.DirInit()
backend.DirInit(false)
os.MkdirAll(backend.ConfigDir+backend.PathSeparator+"deletions", 0700)
case "version", "-v":
versionServer()
+7 -7
View File
@@ -21,11 +21,11 @@ func determineIndentation(skippedDirList []bool, dirList []string, currentDirInd
var lastPrefixIndex int // tracks the index (in both skippedDirList and dirList) of the last displayed parent directory
var trimmedDirectory = dirList[currentDirIndex]
// determine initial indentation multiplier based on PathSeparator occurrences
indent := strings.Count(trimmedDirectory, backend.PathSeparator) - 1 // subtract 1 to avoid indenting root-level directories
// determine initial indentation multiplier based on "/" occurrences
indent := strings.Count(trimmedDirectory, "/") - 1 // subtract 1 to avoid indenting root-level directories
for i, skipped := range skippedDirList[:currentDirIndex] { // checks each skipped directory to determine if it is a parent to the current directory
if strings.HasPrefix(trimmedDirectory, dirList[i]+backend.PathSeparator) { // if the current directory is the child of this iteration's directory...
if strings.HasPrefix(trimmedDirectory, dirList[i]+"/") { // if the current directory is the child of this iteration's directory...
if skipped { // ...and this iteration's directory was skipped...
subtractor++ // increment the subtractor to indicate that the visual indentation should be reduced
} else {
@@ -106,7 +106,7 @@ func EntryListGen() {
// check if next directory is within the current one
if dirListLength > i+1 {
if nextDir := dirList[i+1]; directory == nextDir[:strings.LastIndex(nextDir, backend.PathSeparator)] {
if nextDir := dirList[i+1]; directory == nextDir[:strings.LastIndex(nextDir, "/")] {
containsSubdirectory = true
} else {
containsSubdirectory = false
@@ -120,14 +120,14 @@ func EntryListGen() {
for _, file := range fileList {
// print the current file if it belongs in the current directory - otherwise, break the loop and move on to the next directory
if lastSlash := strings.LastIndex(file, backend.PathSeparator) + 1; file[:lastSlash-1] == directory {
if lastSlash := strings.LastIndex(file, "/") + 1; file[:lastSlash-1] == directory {
// print directory header if this is the first run of the loop
if !containsFiles {
containsFiles = true
skippedDirList[i] = false // the directory header is being printed, indicate that it is not being skipped
indent, vanityDirectory = determineIndentation(skippedDirList, dirList, i) // calculate the final indentation multiplier
printDirectoryHeader(vanityDirectory, indent)
fmt.Printf("\n\n"+strings.Repeat(" ", indent*2)+ansiDirectoryHeader+"%s/"+backend.AnsiReset+"\n", vanityDirectory)
}
charCounter, colorAlternator = printFileEntry(file, lastSlash, charCounter, indent, colorAlternator)
@@ -139,7 +139,7 @@ func EntryListGen() {
if dirListLength > 1 { // and directories besides the root-level exist... display directory header and empty directory warning
skippedDirList[i] = false // the directory header is being printed, indicate that it is not being skipped
indent, vanityDirectory = determineIndentation(skippedDirList, dirList, i) // calculate the final indentation multiplier
printDirectoryHeader(vanityDirectory, indent)
fmt.Printf("\n\n"+strings.Repeat(" ", indent*2)+ansiDirectoryHeader+"%s/"+backend.AnsiReset+"\n", vanityDirectory)
fmt.Print(strings.Repeat(" ", indent*2) + ansiEmptyDirectoryWarning + "-empty directory-" + backend.AnsiReset)
} else { // warn if the only thing that exists is the root-level directory
fmt.Print("\n\nNothing's here! For help creating your first entry, run \"mutn help\".")
-13
View File
@@ -1,13 +0,0 @@
//go:build !windows
package cli
import (
"fmt"
"github.com/rwinkhart/MUTN/src/backend"
"strings"
)
func printDirectoryHeader(vanityDirectory string, indent int) {
fmt.Printf("\n\n"+strings.Repeat(" ", indent*2)+ansiDirectoryHeader+"%s/"+backend.AnsiReset+"\n", vanityDirectory)
}
-13
View File
@@ -1,13 +0,0 @@
//go:build windows
package cli
import (
"fmt"
"github.com/rwinkhart/MUTN/src/backend"
"strings"
)
func printDirectoryHeader(vanityDirectory string, indent int) {
fmt.Printf("\n\n"+strings.Repeat(" ", indent*2)+ansiDirectoryHeader+"%s/"+backend.AnsiReset+"\n", strings.ReplaceAll(vanityDirectory, backend.PathSeparator, "/"))
}
+1 -1
View File
@@ -40,7 +40,7 @@ func TempInitCli() {
sshKeyProtected := inputBinary("Is the identity file password-protected?")
// write config file
backend.TempInit(map[string]string{"textEditor": textEditor, "gpgID": gpgID, "sshUser": sshUser, "sshIP": sshIP, "sshPort": sshPort, "sshKey": sshKey, "sshKeyProtected": strconv.FormatBool(sshKeyProtected)}, false)
backend.TempInit(map[string]string{"textEditor": textEditor, "gpgID": gpgID, "sshUser": sshUser, "sshIP": sshIP, "sshPort": sshPort, "sshKey": sshKey, "sshKeyProtected": strconv.FormatBool(sshKeyProtected), "sshEntryRoot": "null", "sshIsWindows": "null"}, false)
// generate device ID
sshEntryRoot, sshIsWindows := sync.DeviceIDGen()
+1 -1
View File
@@ -260,7 +260,7 @@ func sftpSync(downloadList, uploadList []string, manualSync bool) {
localFile.Close()
// set the modification time of the local file to match the value saved from the remote file (from before the download)
err = os.Chtimes(remoteEntryFullPath, time.Now(), modTime)
err = os.Chtimes(localEntryFullPath, time.Now(), modTime)
}
if filesTransfered {
-39
View File
@@ -3,49 +3,10 @@ package sync
import (
"fmt"
"github.com/rwinkhart/MUTN/src/backend"
"io/fs"
"os"
"path/filepath"
"strings"
)
// WalkEntryDir walks the entry directory and returns lists of all files and directories found (two separate lists)
func WalkEntryDir() ([]string, []string) {
// define file/directory containing slices so that they may be accessed by the anonymous WalkDir function
var fileList []string
var dirList []string
// walk entry directory
_ = filepath.WalkDir(backend.EntryRoot,
func(fullPath string, entry fs.DirEntry, err error) error {
// check for errors encountered while walking directory
if err != nil {
if os.IsNotExist(err) {
fmt.Println(backend.AnsiError+"The entry directory does not exist - run \""+os.Args[0], "init"+"\" to create it"+backend.AnsiReset) // TODO implement init command for libmuttonserver
} else {
// otherwise, print the source of the error
fmt.Println(backend.AnsiError + "An unexpected error occurred while generating the entry list: " + err.Error() + backend.AnsiReset)
}
os.Exit(1)
}
// trim root path from each path before storing
trimmedPath := fullPath[rootLength:]
// create separate slices for entries and directories
if !entry.IsDir() {
fileList = append(fileList, trimmedPath)
} else {
dirList = append(dirList, trimmedPath)
}
return nil
})
return fileList, dirList
}
func getModTimes(entryList []string) []int64 {
// get a list of all entry modification times
var modList []int64
+49
View File
@@ -0,0 +1,49 @@
//go:build !windows
package sync
import (
"fmt"
"github.com/rwinkhart/MUTN/src/backend"
"io/fs"
"os"
"path/filepath"
)
// WalkEntryDir walks the entry directory and returns lists of all files and directories found (two separate lists)
// regardless of platform, all paths are stored with forward slashes (UNIX-style)
func WalkEntryDir() ([]string, []string) {
// define file/directory containing slices so that they may be accessed by the anonymous WalkDir function
var fileList []string
var dirList []string
// walk entry directory
_ = filepath.WalkDir(backend.EntryRoot,
func(fullPath string, entry fs.DirEntry, err error) error {
// check for errors encountered while walking directory
if err != nil {
if os.IsNotExist(err) {
fmt.Println(backend.AnsiError+"The entry directory does not exist - run \""+os.Args[0], "init"+"\" to create it"+backend.AnsiReset) // TODO implement init command for libmuttonserver
} else {
// otherwise, print the source of the error
fmt.Println(backend.AnsiError + "An unexpected error occurred while generating the entry list: " + err.Error() + backend.AnsiReset)
}
os.Exit(1)
}
// trim root path from each path before storing
trimmedPath := fullPath[rootLength:]
// append the path to the appropriate slice
if !entry.IsDir() {
fileList = append(fileList, trimmedPath)
} else {
dirList = append(dirList, trimmedPath)
}
return nil
})
return fileList, dirList
}
+50
View File
@@ -0,0 +1,50 @@
//go:build windows
package sync
import (
"fmt"
"github.com/rwinkhart/MUTN/src/backend"
"io/fs"
"os"
"path/filepath"
"strings"
)
// WalkEntryDir walks the entry directory and returns lists of all files and directories found (two separate lists)
// regardless of platform, all paths are stored with forward slashes (UNIX-style)
func WalkEntryDir() ([]string, []string) {
// define file/directory containing slices so that they may be accessed by the anonymous WalkDir function
var fileList []string
var dirList []string
// walk entry directory
_ = filepath.WalkDir(backend.EntryRoot,
func(fullPath string, entry fs.DirEntry, err error) error {
// check for errors encountered while walking directory
if err != nil {
if os.IsNotExist(err) {
fmt.Println(backend.AnsiError+"The entry directory does not exist - run \""+os.Args[0], "init"+"\" to create it"+backend.AnsiReset) // TODO implement init command for libmuttonserver
} else {
// otherwise, print the source of the error
fmt.Println(backend.AnsiError + "An unexpected error occurred while generating the entry list: " + err.Error() + backend.AnsiReset)
}
os.Exit(1)
}
// trim root path from each path before storing and replace backslashes with forward slashes
trimmedPath := strings.ReplaceAll(fullPath[rootLength:], "\\", "/")
// append the path to the appropriate slice
if !entry.IsDir() {
fileList = append(fileList, trimmedPath)
} else {
dirList = append(dirList, trimmedPath)
}
return nil
})
return fileList, dirList
}
+2 -2
View File
@@ -14,8 +14,8 @@ func DeviceIDGen() (string, string) {
deviceIDPrefix, _ := os.Hostname()
deviceIDSuffix := backend.StringGen(rand.Intn(48)+48, false, 0) // TODO consider using complex string generator and removing unsafe characters manually
deviceID := deviceIDPrefix + "-" + deviceIDSuffix
os.Create(backend.ConfigDir + backend.PathSeparator + "devices" + backend.PathSeparator + deviceID) // TODO remove existing device ID file if it exists (from both client and server)
sshEntryRootSSHIsWindows := strings.Split(GetSSHOutput("libmuttonserver register "+deviceID, false), "\x1d") // register device ID with server and fetch remote EntryRoot and OS type
os.Create(backend.ConfigDir + backend.PathSeparator + "devices" + backend.PathSeparator + deviceID) // TODO remove existing device ID file if it exists (from both client and server)
sshEntryRootSSHIsWindows := strings.Split(GetSSHOutput("libmuttonserver register "+deviceID, true), "\x1d") // register device ID with server and fetch remote EntryRoot and OS type; manualSync is true so the user is alerted if device ID registration fails
return sshEntryRootSSHIsWindows[0], sshEntryRootSSHIsWindows[1]
}
+3 -3
View File
@@ -23,7 +23,7 @@ func GetRemoteDataFromServer(clientDeviceID string) {
// entry list
for _, entry := range entryList {
printToStdout(entry)
fmt.Print("\x1f" + entry)
}
// modification time list
@@ -36,7 +36,7 @@ func GetRemoteDataFromServer(clientDeviceID string) {
// directory/folder list
fmt.Print("\x1d")
for _, dir := range dirList {
printToStdout(dir)
fmt.Print("\x1f" + dir)
}
// deletions list
@@ -45,7 +45,7 @@ func GetRemoteDataFromServer(clientDeviceID string) {
// print deletion if it is relevant to the current client device
affectedIDTargetLocationIncomplete := strings.Split(deletion.Name(), "\x1d")
if affectedIDTargetLocationIncomplete[0] == clientDeviceID {
fmt.Print("\x1f" + strings.ReplaceAll(affectedIDTargetLocationIncomplete[1], "\x1e", "/")) // do not use printToStdout as separators are filling in for \x1e
fmt.Print("\x1f" + strings.ReplaceAll(affectedIDTargetLocationIncomplete[1], "\x1e", "/"))
// assume successful client deletion and remove deletions file (if assumption is somehow false, worst case scenario is that the client will re-upload the deleted entry)
os.Remove(backend.ConfigDir + backend.PathSeparator + "deletions" + backend.PathSeparator + deletion.Name())
-12
View File
@@ -1,12 +0,0 @@
//go:build !windows
package sync
import (
"fmt"
)
// printToStdout prints a string to stdout with UNIX path separators
func printToStdout(targetLocationIncomplete string) {
fmt.Print("\x1f" + targetLocationIncomplete)
}
-13
View File
@@ -1,13 +0,0 @@
//go:build windows
package sync
import (
"fmt"
"strings"
)
// printToStdout prints a string to stdout with UNIX path separators
func printToStdout(targetLocationIncomplete string) {
fmt.Print("\x1f" + strings.ReplaceAll(targetLocationIncomplete, "\\", "/"))
}