From d5146d7625c6ca49c1db05cc82fcb21070cd7586 Mon Sep 17 00:00:00 2001 From: Randall Winkhart Date: Wed, 10 Jul 2024 00:01:59 -0400 Subject: [PATCH] Split sync.Rename into separate functions for client and server to avoid compiling SSH into the server binary --- src/sync/client.go | 40 ++++++++++++++++++++++-------- src/sync/common.go | 62 +++++++++++++++++++--------------------------- 2 files changed, 55 insertions(+), 47 deletions(-) diff --git a/src/sync/client.go b/src/sync/client.go index a0bbd16..636ee9e 100644 --- a/src/sync/client.go +++ b/src/sync/client.go @@ -370,17 +370,6 @@ func syncLists(localEntryModMap, remoteEntryModMap map[string]int64, manualSync fmt.Println("Client is synchronized with server") } -// ShearRemoteFromClient removes the target file or directory from the local system and calls the server to remove it remotely and add it to the deletions list -// can safely be called in offline mode, as well, so this is the intended interface for shearing (ShearLocal should only be used directly in the server binary) -func ShearRemoteFromClient(targetLocationIncomplete string) { - deviceID := ShearLocal(targetLocationIncomplete, "") // remove the target from the local system and get the device ID of the client - - // call the server to remotely shear the target and add it to the deletions list - GetSSHOutput("libmuttonserver shear", deviceID+"\n"+strings.ReplaceAll(targetLocationIncomplete, backend.PathSeparator, "\x1d"), false) - - backend.Exit(0) // sync is not required after shearing since the target has already been removed from the local system -} - // deletionSync removes entries from the client that have been deleted on the server (multi-client deletion) func deletionSync(deletions []string) { var filesDeleted bool @@ -395,7 +384,36 @@ func deletionSync(deletions []string) { } } +// ShearRemoteFromClient removes the target file or directory from the local system and calls the server to remove it remotely and add it to the deletions list +// can safely be called in offline mode, as well, so this is the intended interface for shearing (ShearLocal should only be used directly by the server binary) +func ShearRemoteFromClient(targetLocationIncomplete string) { + deviceID := ShearLocal(targetLocationIncomplete, "") // remove the target from the local system and get the device ID of the client + + // call the server to remotely shear the target and add it to the deletions list + GetSSHOutput("libmuttonserver shear", deviceID+"\n"+strings.ReplaceAll(targetLocationIncomplete, backend.PathSeparator, "\x1d"), false) + + backend.Exit(0) // sync is not required after shearing since the target has already been removed from the local system +} + +// RenameRemoteFromClient renames oldLocationIncomplete to newLocationIncomplete on the local system and calls the server to perform the rename remotely and add the old target to the deletions list +// can safely be called in offline mode, as well, so this is the intended interface for renaming (RenameLocal should only be used directly by the server binary) +func RenameRemoteFromClient(oldLocationIncomplete, newLocationIncomplete string) { + RenameLocal(oldLocationIncomplete, newLocationIncomplete) // move the target on the local system + + deviceIDList := genDeviceIDList() + if len(*deviceIDList) > 0 { // ensure a device ID exists (online mode) + // call the server to move the target on the remote system and add the old target to the deletions list + GetSSHOutput("libmuttonserver rename", + (*deviceIDList)[0].Name()+"\n"+ + strings.ReplaceAll(oldLocationIncomplete, backend.PathSeparator, "\x1d")+"\n"+ + strings.ReplaceAll(newLocationIncomplete, backend.PathSeparator, "\x1d"), false) + } + + backend.Exit(0) +} + // AddFolderRemoteFromClient creates a new entry-containing directory on the local system and calls the server to create the folder remotely +// can safely be called in offline mode, as well, so this is the intended interface for adding folders (AddFolderLocal should only be used directly by the server binary) func AddFolderRemoteFromClient(targetLocationIncomplete string) { AddFolderLocal(targetLocationIncomplete) // add the folder on the local system GetSSHOutput("libmuttonserver addfolder", strings.ReplaceAll(targetLocationIncomplete, backend.PathSeparator, "\x1d"), false) // call the server to create the folder remotely diff --git a/src/sync/common.go b/src/sync/common.go index 58aec5c..110997d 100644 --- a/src/sync/common.go +++ b/src/sync/common.go @@ -30,42 +30,6 @@ func genDeviceIDList() *[]fs.DirEntry { 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) @@ -112,6 +76,32 @@ func ShearLocal(targetLocationIncomplete, clientDeviceID string) string { // do not exit program, as this function is used as part of ShearRemoteFromClient } +// RenameLocal renames oldLocationIncomplete to newLocationIncomplete on the local system +// this function should only be used directly by the server binary +func RenameLocal(oldLocationIncomplete, newLocationIncomplete string) { + // 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) + } + + // do not exit program, as this function is used as part of RenameRemoteFromClient +} + // AddFolderLocal creates a new entry-containing directory on the local system // this function should only be used directly by the server binary func AddFolderLocal(targetLocationIncomplete string) {