Skip to content
This repository was archived by the owner on Jul 8, 2020. It is now read-only.

Commit e8484ac

Browse files
committed
Merge branch 'master' of github.com:goftp/server
2 parents b60255f + fa63b56 commit e8484ac

4 files changed

Lines changed: 71 additions & 38 deletions

File tree

cmd.go

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ func (cmd commandList) Execute(conn *Conn, param string) {
351351
for _, field := range fields {
352352
if strings.HasPrefix(field, "-") {
353353
//TODO: currently ignore all the flag
354-
fpath = conn.namePrefix
354+
//fpath = conn.namePrefix
355355
} else {
356356
fpath = field
357357
}
@@ -398,9 +398,34 @@ func (cmd commandNlst) RequireAuth() bool {
398398

399399
func (cmd commandNlst) Execute(conn *Conn, param string) {
400400
conn.writeMessage(150, "Opening ASCII mode data connection for file list")
401-
path := conn.buildPath(param)
401+
var fpath string
402+
if len(param) == 0 {
403+
fpath = param
404+
} else {
405+
fields := strings.Fields(param)
406+
for _, field := range fields {
407+
if strings.HasPrefix(field, "-") {
408+
//TODO: currently ignore all the flag
409+
//fpath = conn.namePrefix
410+
} else {
411+
fpath = field
412+
}
413+
}
414+
}
415+
416+
path := conn.buildPath(fpath)
417+
info, err := conn.driver.Stat(path)
418+
if err != nil {
419+
conn.writeMessage(550, err.Error())
420+
return
421+
}
422+
if !info.IsDir() {
423+
// TODO: should we show the file description?
424+
return
425+
}
426+
402427
var files []FileInfo
403-
err := conn.driver.ListDir(path, func(f FileInfo) error {
428+
err = conn.driver.ListDir(path, func(f FileInfo) error {
404429
files = append(files, f)
405430
return nil
406431
})

conn.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,11 @@ func (Conn *Conn) buildPath(filename string) (fullPath string) {
151151
// data socket. Assumes the socket is open and ready to be used.
152152
func (Conn *Conn) sendOutofbandData(data []byte) {
153153
bytes := len(data)
154-
Conn.dataConn.Write(data)
155-
Conn.dataConn.Close()
156-
Conn.dataConn = nil
154+
if Conn.dataConn != nil {
155+
Conn.dataConn.Write(data)
156+
Conn.dataConn.Close()
157+
Conn.dataConn = nil
158+
}
157159
message := "Closing data connection, sent " + strconv.Itoa(bytes) + " bytes"
158160
Conn.writeMessage(226, message)
159161
}

server.go

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ type Server struct {
5353
listenTo string
5454
driverFactory DriverFactory
5555
logger *Logger
56+
listener net.Listener
5657
}
5758

5859
// serverOptsWithDefaults copies an ServerOpts struct into a new struct,
@@ -186,23 +187,34 @@ func (Server *Server) ListenAndServe() error {
186187

187188
Server.logger.Printf("%s listening on %d", Server.Name, Server.Port)
188189

190+
Server.listener = listener
189191
for {
190-
tcpConn, err := listener.Accept()
192+
tcpConn, err := Server.listener.Accept()
191193
if err != nil {
192-
Server.logger.Print("listening error")
194+
Server.logger.Printf("listening error: %v", err)
193195
break
194196
}
195197
driver, err := Server.driverFactory.NewDriver()
196198
if err != nil {
197-
Server.logger.Print("Error creating driver, aborting client connection")
198-
break
199+
Server.logger.Printf("Error creating driver, aborting client connection: %v", err)
200+
tcpConn.Close()
201+
} else {
202+
ftpConn := Server.newConn(tcpConn, driver, Server.Auth)
203+
go ftpConn.Serve()
199204
}
200-
ftpConn := Server.newConn(tcpConn, driver, Server.Auth)
201-
go ftpConn.Serve()
202205
}
203206
return nil
204207
}
205208

209+
// Gracefully stops a server. Already connected clients will retain their connections
210+
func (Server *Server) Shutdown() error {
211+
if Server.listener != nil {
212+
return Server.listener.Close()
213+
}
214+
// server wasnt even started
215+
return nil
216+
}
217+
206218
func buildTcpString(hostname string, port int) (result string) {
207219
if strings.Contains(hostname, ":") {
208220
// ipv6

socket.go

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"net"
66
"strconv"
77
"strings"
8-
"time"
8+
"sync"
99
)
1010

1111
// A data socket is used to send non-control data between the client and
@@ -80,6 +80,7 @@ type ftpPassiveSocket struct {
8080
ingress chan []byte
8181
egress chan []byte
8282
logger *Logger
83+
wg sync.WaitGroup
8384
}
8485

8586
func newPassiveSocket(host string, logger *Logger) (DataSocket, error) {
@@ -88,12 +89,8 @@ func newPassiveSocket(host string, logger *Logger) (DataSocket, error) {
8889
socket.egress = make(chan []byte)
8990
socket.logger = logger
9091
socket.host = host
91-
go socket.ListenAndServe()
92-
for {
93-
if socket.Port() > 0 {
94-
break
95-
}
96-
time.Sleep(100 * time.Millisecond)
92+
if err := socket.GoListenAndServe(); err != nil {
93+
return nil, err
9794
}
9895
return socket, nil
9996
}
@@ -128,7 +125,7 @@ func (socket *ftpPassiveSocket) Close() error {
128125
return nil
129126
}
130127

131-
func (socket *ftpPassiveSocket) ListenAndServe() {
128+
func (socket *ftpPassiveSocket) GoListenAndServe() (err error) {
132129
laddr, err := net.ResolveTCPAddr("tcp", "0.0.0.0:0")
133130
if err != nil {
134131
socket.logger.Print(err)
@@ -148,26 +145,23 @@ func (socket *ftpPassiveSocket) ListenAndServe() {
148145
}
149146

150147
socket.port = port
151-
tcpConn, err := listener.AcceptTCP()
152-
if err != nil {
153-
socket.logger.Print(err)
154-
return
155-
}
156-
socket.conn = tcpConn
148+
socket.wg.Add(1)
149+
go func() {
150+
tcpConn, err := listener.AcceptTCP()
151+
socket.wg.Done()
152+
if err != nil {
153+
socket.logger.Print(err)
154+
return
155+
}
156+
socket.conn = tcpConn
157+
}()
158+
return nil
157159
}
158160

159161
func (socket *ftpPassiveSocket) waitForOpenSocket() bool {
160-
retries := 0
161-
for {
162-
if socket.conn != nil {
163-
break
164-
}
165-
if retries > 3 {
166-
socket.logger.Print("socket isn't open")
167-
return false
168-
}
169-
time.Sleep(500 * time.Millisecond)
170-
retries += 1
162+
if socket.conn != nil {
163+
return true
171164
}
172-
return true
165+
socket.wg.Wait()
166+
return socket.conn != nil
173167
}

0 commit comments

Comments
 (0)