package ftpserver import ( "Scanyonero/document" "fmt" "sync" ftpserverlib "github.com/fclairamb/ftpserverlib" ) type FTPServer struct { files chan document.File ftpServer *ftpserverlib.FtpServer } // NewFTPServer returns a new FTP server instance. // This will also start the server. func NewFTPServer(user, pass, listenAddr string) (*FTPServer, error) { fs := &virtualFS{} driver := &driver{ User: user, Pass: pass, ListenAddr: listenAddr, ClientDriver: fs, } s := &FTPServer{ files: make(chan document.File), ftpServer: ftpserverlib.NewFtpServer(driver), } // Handler callback for newly uploaded files. // We will pass the files into the files channel. var closed bool var mutex sync.Mutex fs.Callback = func(file document.File) error { mutex.Lock() defer mutex.Unlock() if closed { return fmt.Errorf("server is closing") } s.files <- file return nil } // Create listener. if err := s.ftpServer.Listen(); err != nil { return nil, err } // Start listening. go func() { s.ftpServer.Serve() // We will be shutting down everything soon. // Ensure that no new files will be written into the files channel. mutex.Lock() closed = true mutex.Unlock() close(s.files) }() return s, nil } // Returns the file channel where files uploaded to the FTP-Server will be sent to. // // The channel will automatically be closed after Stop() has been called. func (s *FTPServer) FileChan() <-chan document.File { return s.files } // Shuts the FTP-Server down. func (s *FTPServer) Stop() error { return s.ftpServer.Stop() }