diff --git a/client.go b/client.go index 3139173..93cbc88 100644 --- a/client.go +++ b/client.go @@ -235,6 +235,7 @@ func (c *Client) ReadDir(p string) ([]os.FileInfo, error) { } return attrs, err } + func (c *Client) opendir(path string) (string, error) { id := c.nextId() typ, data, err := c.sendRequest(sshFxpOpendirPacket{ @@ -607,6 +608,40 @@ func (c *Client) Rename(oldname, newname string) error { } } +func (c *Client) realpath(path string) (string, error) { + id := c.nextId() + typ, data, err := c.sendRequest(sshFxpRealpathPacket{ + Id: id, + Path: path, + }) + if err != nil { + return "", err + } + switch typ { + case ssh_FXP_NAME: + sid, data := unmarshalUint32(data) + if sid != id { + return "", &unexpectedIdErr{id, sid} + } + count, data := unmarshalUint32(data) + if count != 1 { + return "", unexpectedCount(1, count) + } + filename, _ := unmarshalString(data) // ignore attributes + return filename, nil + case ssh_FXP_STATUS: + return "", okOrErr(unmarshalStatus(id, data)) + default: + return "", unimplementedPacketErr(typ) + } +} + +// Getwd returns the current working directory of the server. Operations +// involving relative paths will be based at this location. +func (c *Client) Getwd() (string, error) { + return c.realpath(".") +} + // result captures the result of receiving the a packet from the server type result struct { typ byte diff --git a/client_integration_test.go b/client_integration_test.go index 774c393..c50a859 100644 --- a/client_integration_test.go +++ b/client_integration_test.go @@ -503,6 +503,27 @@ func TestClientRename(t *testing.T) { } } +func TestClientGetwd(t *testing.T) { + sftp, cmd := testClient(t, READONLY, NO_DELAY) + defer cmd.Wait() + defer sftp.Close() + + lwd, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + rwd, err := sftp.Getwd() + if err != nil { + t.Fatal(err) + } + if !path.IsAbs(rwd) { + t.Fatalf("Getwd: wanted absolute path, got %q", rwd) + } + if lwd != rwd { + t.Fatalf("Getwd: want %q, got %q", lwd, rwd) + } +} + func TestClientReadLink(t *testing.T) { sftp, cmd := testClient(t, READWRITE, NO_DELAY) defer cmd.Wait() diff --git a/packet.go b/packet.go index 5954932..697d884 100644 --- a/packet.go +++ b/packet.go @@ -439,7 +439,7 @@ type sshFxpRealpathPacket struct { func (p sshFxpRealpathPacket) id() uint32 { return p.Id } func (p sshFxpRealpathPacket) MarshalBinary() ([]byte, error) { - return marshalIdString(ssh_FXP_READLINK, p.Id, p.Path) + return marshalIdString(ssh_FXP_REALPATH, p.Id, p.Path) } func (p *sshFxpRealpathPacket) UnmarshalBinary(b []byte) error {