Skip to content

Commit

Permalink
Added MKDIR and RMDIR site commands (#205)
Browse files Browse the repository at this point in the history
* Added MKDIR and RMDIR site commands.
* golangci config + version updates
  • Loading branch information
fclairamb authored Dec 18, 2020
1 parent 6678256 commit 489ebc8
Show file tree
Hide file tree
Showing 13 changed files with 184 additions and 31 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
if: matrix.lint
uses: golangci/golangci-lint-action@v2
with:
version: v1.30
version: v1.33

# Install Go
- name: Setup go
Expand Down
22 changes: 9 additions & 13 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,6 @@ linters-settings:
range-loops: true # Report preallocation suggestions on range loops, true by default
for-loops: false # Report preallocation suggestions on for loops, false by default
gocritic:
# Which checks should be enabled; can't be combined with 'disabled-checks';
# See https://go-critic.github.io/overview#checks-overview
# To check which checks are enabled run `GL_DEBUG=gocritic golangci-lint run`
# By default list of stable checks is used.
enabled-checks:

# Which checks should be disabled; can't be combined with 'enabled-checks'; default is empty
disabled-checks:

# Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.
# Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags".
enabled-tags:
Expand Down Expand Up @@ -169,15 +160,21 @@ linters-settings:
force-case-trailing-whitespace: 0

linters:
disable-all: true
enable:
- bodyclose
- deadcode
- depguard
- dogsled
- dupl
- errcheck
- exhaustive
# - exhaustivestruct
- exportloopref
- funlen
# - gci
- gochecknoinits
# - gochecknoglobals
- gocognit
- goconst
- gocritic
Expand All @@ -199,6 +196,8 @@ linters:
- megacheck
- misspell
- nakedret
# - nestif
- nlreturn
- prealloc
- nolintlint
- rowserrcheck
Expand All @@ -212,11 +211,8 @@ linters:
- unused
- varcheck
- whitespace
# - wrapcheck
- wsl
disable-all: false
presets:
- bugs
- unused
fast: false

issues:
Expand Down
4 changes: 4 additions & 0 deletions client_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ func (c *clientHandler) HandleCommands() {
c.writeMessage(StatusServiceReady, msg)
} else {
c.writeMessage(StatusSyntaxErrorNotRecognised, msg)

return
}

Expand All @@ -235,6 +236,7 @@ func (c *clientHandler) HandleCommands() {

if err != nil {
c.handleCommandsStreamError(err)

return
}

Expand Down Expand Up @@ -293,11 +295,13 @@ func (c *clientHandler) handleCommand(line string) {
cmdDesc := commandsMap[c.command]
if cmdDesc == nil {
c.writeMessage(StatusSyntaxErrorNotRecognised, "Unknown command")

return
}

if c.driver == nil && !cmdDesc.Open {
c.writeMessage(StatusNotLoggedIn, "Please login with USER and PASS")

return
}

Expand Down
1 change: 1 addition & 0 deletions handle_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import "fmt"
func (c *clientHandler) handleUSER() error {
if c.server.settings.TLSRequired == MandatoryEncryption && !c.controlTLS {
c.writeMessage(StatusServiceNotAvailable, "TLS is required")

return nil
}

Expand Down
39 changes: 38 additions & 1 deletion handle_dirs.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,22 @@ func (c *clientHandler) handleMKD() error {
return nil
}

func (c *clientHandler) handleMKDIR(params string) {
if params == "" {
c.writeMessage(StatusSyntaxErrorNotRecognised, "Missing path")

return
}

p := c.absPath(params)

if err := c.driver.MkdirAll(p, 0755); err == nil {
c.writeMessage(StatusFileOK, fmt.Sprintf("Created dir %s", p))
} else {
c.writeMessage(StatusActionNotTaken, fmt.Sprintf("Couldn't create dir %s: %v", p, err))
}
}

func (c *clientHandler) handleRMD() error {
var err error

Expand All @@ -69,6 +85,22 @@ func (c *clientHandler) handleRMD() error {
return nil
}

func (c *clientHandler) handleRMDIR(params string) {
if params == "" {
c.writeMessage(StatusSyntaxErrorNotRecognised, "Missing path")

return
}

p := c.absPath(params)

if err := c.driver.RemoveAll(p); err == nil {
c.writeMessage(StatusFileOK, fmt.Sprintf("Removed dir %s", p))
} else {
c.writeMessage(StatusActionNotTaken, fmt.Sprintf("Couldn't remove dir %s: %v", p, err))
}
}

func (c *clientHandler) handleCDUP() error {
parent, _ := path.Split(c.Path())
if parent != "/" && strings.HasSuffix(parent, "/") {
Expand All @@ -87,6 +119,7 @@ func (c *clientHandler) handleCDUP() error {

func (c *clientHandler) handlePWD() error {
c.writeMessage(StatusPathCreated, "\""+c.Path()+"\" is the current directory")

return nil
}

Expand Down Expand Up @@ -134,7 +167,7 @@ func (c *clientHandler) handleNLST() error {
return err
}
} else {
c.writeMessage(500, fmt.Sprintf("Could not list: %v", err))
c.writeMessage(StatusSyntaxErrorNotRecognised, fmt.Sprintf("Could not list: %v", err))
}

return nil
Expand All @@ -143,6 +176,7 @@ func (c *clientHandler) handleNLST() error {
func (c *clientHandler) dirTransferNLST(w io.Writer, files []os.FileInfo) error {
if len(files) == 0 {
_, err := w.Write([]byte(""))

return err
}

Expand All @@ -158,6 +192,7 @@ func (c *clientHandler) dirTransferNLST(w io.Writer, files []os.FileInfo) error
func (c *clientHandler) handleMLSD() error {
if c.server.settings.DisableMLSD {
c.writeMessage(StatusSyntaxErrorNotRecognised, "MLSD has been disabled")

return nil
}

Expand Down Expand Up @@ -206,6 +241,7 @@ func (c *clientHandler) fileStat(file os.FileInfo) string {
func (c *clientHandler) dirTransferLIST(w io.Writer, files []os.FileInfo) error {
if len(files) == 0 {
_, err := w.Write([]byte(""))

return err
}

Expand All @@ -222,6 +258,7 @@ func (c *clientHandler) dirTransferLIST(w io.Writer, files []os.FileInfo) error
func (c *clientHandler) dirTransferMLSD(w io.Writer, files []os.FileInfo) error {
if len(files) == 0 {
_, err := w.Write([]byte(""))

return err
}

Expand Down
65 changes: 65 additions & 0 deletions handle_dirs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,71 @@ func TestDirHandling(t *testing.T) {
require.Error(t, err, "We shouldn't have been able to ftpDelete known again")
}

func TestMkdirRmDir(t *testing.T) {
s := NewTestServer(t, true)
conf := goftp.Config{
User: authUser,
Password: authPass,
}

c, err := goftp.DialConfig(conf, s.Addr())
require.NoError(t, err, "Couldn't connect")

defer func() { panicOnError(c.Close()) }()

raw, err := c.OpenRawConn()
require.NoError(t, err, "Couldn't open raw connection")

t.Run("standard", func(t *testing.T) {
rc, _, err := raw.SendCommand("SITE MKDIR /dir1/dir2/dir3")
require.NoError(t, err)
require.Equal(t, StatusFileOK, rc)

for _, d := range []string{"/dir1", "/dir1/dir2", "/dir1/dir2/dir3"} {
stat, errStat := c.Stat(d)
require.NoError(t, errStat)
require.True(t, stat.IsDir())
}

rc, _, err = raw.SendCommand("SITE RMDIR /dir1")
require.NoError(t, err)
require.Equal(t, StatusFileOK, rc)

for _, d := range []string{"/dir1", "/dir1/dir2", "/dir1/dir2/dir3"} {
stat, errStat := c.Stat(d)
require.Error(t, errStat)
require.Nil(t, stat)
}
})

t.Run("syntax error", func(t *testing.T) {
rc, _, err := raw.SendCommand("SITE MKDIR")
require.NoError(t, err)
require.Equal(t, StatusSyntaxErrorNotRecognised, rc)

rc, _, err = raw.SendCommand("SITE RMDIR")
require.NoError(t, err)
require.Equal(t, StatusSyntaxErrorNotRecognised, rc)
})

t.Run("spaces", func(t *testing.T) {
rc, _, err := raw.SendCommand("SITE MKDIR /dir1 /dir2")
require.NoError(t, err)
require.Equal(t, StatusFileOK, rc)

{
dir := "/dir1 /dir2"
stat, errStat := c.Stat(dir)
require.NoError(t, errStat)
require.True(t, stat.IsDir())
}

rc, _, err = raw.SendCommand("SITE RMDIR /dir1 /dir2")
require.NoError(t, err)
require.Equal(t, StatusFileOK, rc)
})
}

// TestDirListingWithSpace uses the MLSD for files listing
func TestDirListingWithSpace(t *testing.T) {
s := NewTestServer(t, true)
Expand Down
Loading

0 comments on commit 489ebc8

Please sign in to comment.