diff --git a/client_test.go b/client_test.go index 75be766..5872a5e 100644 --- a/client_test.go +++ b/client_test.go @@ -417,3 +417,29 @@ func TestDialWithDialer(t *testing.T) { assert.Equal(t, true, dialerCalled) } + +func TestServerConn_Stat(t *testing.T) { + mock, c := openConn(t, "127.0.0.1") + + defer func() { + err := c.Quit() + assert.NoError(t, err) + mock.Close() + }() + + err := c.MakeDir(testDir) + assert.NoError(t, err) + + testFile := testDir + "/testfile.txt" + data := bytes.NewBufferString(testData) + err = c.Stor(testFile, data) + assert.NoError(t, err) + + status, err := c.Stat(testDir) + assert.NoError(t, err) + assert.NotEmpty(t, status, "Expected non-empty status for directory") + + status, err = c.Stat(testFile) + assert.NoError(t, err) + assert.NotEmpty(t, status, "Expected non-empty status for file") +} diff --git a/conn_test.go b/conn_test.go index ab26840..ca11bb5 100644 --- a/conn_test.go +++ b/conn_test.go @@ -279,6 +279,12 @@ func (mock *ftpMock) listen() { case "QUIT": mock.printfLine("221 Goodbye.") return + case "STAT": + if len(cmdParts) > 1 { + mock.printfLine("213-Status follows:\r\n%s\r\n213 End of status", strings.Join(cmdParts[1:], " ")) + } else { + mock.printfLine("213-Status follows:\r\nFTP server status\r\n213 End of status") + } default: mock.printfLine("500 Unknown command %s.", cmdParts[0]) } diff --git a/ftp.go b/ftp.go index 02136ae..6081451 100644 --- a/ftp.go +++ b/ftp.go @@ -1123,6 +1123,15 @@ func (c *ServerConn) Quit() error { return errs.ErrorOrNil() } +// Stat issues a STAT FTP command to obtain the status of a file or directory. +func (c *ServerConn) Stat(path string) (string, error) { + _, msg, err := c.cmd(StatusFile, "STAT %s", path) + if err != nil { + return "", err + } + return msg, nil +} + // Read implements the io.Reader interface on a FTP data connection. func (r *Response) Read(buf []byte) (int, error) { return r.conn.Read(buf)