Skip to content

Commit b97d5b8

Browse files
committed
fix: use path.Join for guest paths, pass FollowLinks to CpToInstance
1 parent f49d6c9 commit b97d5b8

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

lib/cp.go

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"net/http"
1111
"net/url"
1212
"os"
13+
"path"
1314
"path/filepath"
1415
"strings"
1516
"syscall"
@@ -185,12 +186,13 @@ func CpToInstance(ctx context.Context, cfg CpConfig, opts CpToInstanceOptions) e
185186

186187
// Send initial request
187188
req := cpRequest{
188-
Direction: "to",
189-
GuestPath: opts.DstPath,
190-
IsDir: srcInfo.IsDir(),
191-
Mode: uint32(mode),
192-
Uid: uid,
193-
Gid: gid,
189+
Direction: "to",
190+
GuestPath: opts.DstPath,
191+
IsDir: srcInfo.IsDir(),
192+
Mode: uint32(mode),
193+
FollowLinks: opts.FollowLinks,
194+
Uid: uid,
195+
Gid: gid,
194196
}
195197
reqJSON, _ := json.Marshal(req)
196198
if err := ws.WriteMessage(websocket.TextMessage, reqJSON); err != nil {
@@ -292,21 +294,23 @@ func copyDirToWs(ctx context.Context, cfg CpConfig, ws WsConn, srcPath, dstPath,
292294
}
293295

294296
// Now recursively copy contents
295-
return filepath.WalkDir(srcPath, func(path string, d fs.DirEntry, err error) error {
297+
return filepath.WalkDir(srcPath, func(walkPath string, d fs.DirEntry, err error) error {
296298
if err != nil {
297299
return err
298300
}
299301

300-
if path == srcPath {
302+
if walkPath == srcPath {
301303
return nil // Skip root
302304
}
303305

304-
relPath, err := filepath.Rel(srcPath, path)
306+
relPath, err := filepath.Rel(srcPath, walkPath)
305307
if err != nil {
306308
return fmt.Errorf("relative path: %w", err)
307309
}
308310

309-
targetPath := filepath.Join(dstPath, relPath)
311+
// Use path.Join (not filepath.Join) for guest paths to ensure forward slashes
312+
// Convert Windows backslashes to forward slashes for Linux guest
313+
targetPath := path.Join(dstPath, filepath.ToSlash(relPath))
310314
info, err := d.Info()
311315
if err != nil {
312316
return fmt.Errorf("info: %w", err)
@@ -316,7 +320,7 @@ func copyDirToWs(ctx context.Context, cfg CpConfig, ws WsConn, srcPath, dstPath,
316320
// This is because the protocol is one-file-per-connection
317321
return CpToInstance(ctx, cfg, CpToInstanceOptions{
318322
InstanceID: instanceID,
319-
SrcPath: path,
323+
SrcPath: walkPath,
320324
DstPath: targetPath,
321325
Mode: info.Mode().Perm(),
322326
Callbacks: callbacks,

0 commit comments

Comments
 (0)