Implement synchronized renaming

This commit is contained in:
2024-07-09 23:18:13 -04:00
parent f8d23489c0
commit cef8c47161
2 changed files with 55 additions and 36 deletions
-24
View File
@@ -1,10 +1,5 @@
package backend
import (
"fmt"
"os"
)
// GetOldEntryData decrypts and returns old entry data (with all required lines present)
func GetOldEntryData(targetLocation string, field int) []string {
// ensure targetLocation exists
@@ -21,25 +16,6 @@ func GetOldEntryData(targetLocation string, field int) []string {
}
}
// Rename renames oldLocation to newLocation
func Rename(oldLocation, newLocation string) {
// ensure newLocation does not exist
_, isAccessible := TargetIsFile(newLocation, false, 0)
if isAccessible {
fmt.Println(AnsiError + "\"" + newLocation + "\" already exists" + AnsiReset)
os.Exit(1)
}
// rename oldLocation to newLocation
err := os.Rename(oldLocation, newLocation)
if err != nil {
fmt.Println(AnsiError + "Failed to rename - does the target containing directory exists?" + AnsiReset)
}
// TODO implement synced renaming
Exit(0)
}
// EnsureSliceLength ensures slice is long enough to contain the specified index
func EnsureSliceLength(slice []string, index int) []string {
for len(slice) <= index {
+55 -12
View File
@@ -3,12 +3,13 @@ package sync
import (
"fmt"
"github.com/rwinkhart/MUTN/src/backend"
"io/fs"
"os"
"strings"
)
// getModTimes returns a list of all entry modification times
func getModTimes(entryList []string) []int64 {
// get a list of all entry modification times
var modList []int64
for _, file := range entryList {
modTime, _ := os.Stat(backend.TargetLocationFormat(file))
@@ -18,6 +19,53 @@ func getModTimes(entryList []string) []int64 {
return modList
}
// genDeviceIDList returns a pointer to a slice of all registered device IDs
func genDeviceIDList() *[]fs.DirEntry {
// create a slice of all registered devices
deviceIDList, err := os.ReadDir(backend.ConfigDir + backend.PathSeparator + "devices")
if err != nil {
fmt.Println(backend.AnsiError + "Failed to read the devices directory: " + err.Error() + backend.AnsiReset)
os.Exit(1)
}
return &deviceIDList
}
// Rename renames oldLocation to newLocation
// if running on the client, also calls the server to rename the entry and add the old entry name to the deletions list
func Rename(oldLocationIncomplete, newLocationIncomplete string, onServer bool) {
// get full paths for both locations
oldLocation := backend.TargetLocationFormat(oldLocationIncomplete)
newLocation := backend.TargetLocationFormat(newLocationIncomplete)
// ensure oldLocation exists
backend.TargetIsFile(oldLocation, true, 0)
// ensure newLocation does not exist
_, isAccessible := backend.TargetIsFile(newLocation, false, 0)
if isAccessible {
fmt.Println(backend.AnsiError + "\"" + newLocation + "\" already exists" + backend.AnsiReset)
os.Exit(1)
}
// rename oldLocation to newLocation
err := os.Rename(oldLocation, newLocation)
if err != nil {
fmt.Println(backend.AnsiError + "Failed to rename - does the target containing directory exist?" + backend.AnsiReset)
}
// call server to complete rename
if !onServer {
deviceIDList := genDeviceIDList()
if len(*deviceIDList) > 0 { // ensure a device ID exists (online mode)
GetSSHOutput("libmuttonserver rename",
(*deviceIDList)[0].Name()+"\n"+
strings.ReplaceAll(oldLocationIncomplete, backend.PathSeparator, "\x1d")+"\n"+
strings.ReplaceAll(newLocationIncomplete, backend.PathSeparator, "\x1d"), false)
}
backend.Exit(0) // do not exit program on server, as fallthrough is used to add the old entry name to the deletions list
}
}
// ShearLocal removes the target file or directory from the local system
// returns: deviceID (on client), for use in ShearRemoteFromClient
// if the local system is a server, it will also add the target to the deletions list for all clients (except the requesting client)
@@ -29,18 +77,13 @@ func ShearLocal(targetLocationIncomplete, clientDeviceID string) string {
onServer = true
}
// create a slice of all registered devices
deviceIDList, err := os.ReadDir(backend.ConfigDir + backend.PathSeparator + "devices")
if err != nil {
fmt.Println(backend.AnsiError + "Failed to read the devices directory: " + err.Error() + backend.AnsiReset)
os.Exit(1)
}
deviceIDList := genDeviceIDList()
// add the sheared target (incomplete, vanity) to the deletions list (if running on a server)
if onServer {
for _, device := range deviceIDList {
for _, device := range *deviceIDList {
if device.Name() != clientDeviceID {
_, err = os.Create(backend.ConfigDir + backend.PathSeparator + "deletions" + backend.PathSeparator + device.Name() + "\x1e" + strings.ReplaceAll(targetLocationIncomplete, "/", "\x1d"))
_, err := os.Create(backend.ConfigDir + backend.PathSeparator + "deletions" + backend.PathSeparator + device.Name() + "\x1e" + strings.ReplaceAll(targetLocationIncomplete, "/", "\x1d"))
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)
@@ -55,14 +98,14 @@ func ShearLocal(targetLocationIncomplete, clientDeviceID string) string {
if !onServer { // error if target does not exist on client, needed because os.RemoveAll does not return an error if target does not exist
backend.TargetIsFile(targetLocationComplete, true, 0)
}
err = os.RemoveAll(targetLocationComplete)
err := os.RemoveAll(targetLocationComplete)
if err != nil {
fmt.Println(backend.AnsiError + "Failed to remove local target: " + err.Error() + backend.AnsiReset)
os.Exit(1)
}
if !onServer && len(deviceIDList) > 0 { // return the device ID if running on the client and a device ID exists (online mode)
return deviceIDList[0].Name()
if !onServer && len(*deviceIDList) > 0 { // return the device ID if running on the client and a device ID exists (online mode)
return (*deviceIDList)[0].Name()
}
return ""