From e78e556b63b439f880cdf510ea8a29e83f08dd70 Mon Sep 17 00:00:00 2001 From: schwarzlichtbezirk Date: Mon, 10 Apr 2023 05:31:37 +0300 Subject: [PATCH] fix with FtpPwdPath. --- cache.go | 3 +-- ftpio.go | 41 ++++++++++++++++++++++++----------------- io.go | 3 +-- opendisk.go | 15 +++++---------- profile.go | 9 +++------ 5 files changed, 34 insertions(+), 37 deletions(-) diff --git a/cache.go b/cache.go index 1ad0134..07b789d 100644 --- a/cache.go +++ b/cache.go @@ -131,9 +131,8 @@ func (c *Cache[K, T]) Remove(key K) (ok bool) { } func (c *Cache[K, T]) Enum(f func(K, T) bool) { - var s = make([]kvcell[K, T], len(c.s)) c.mux.Lock() - copy(s, c.s) + var s = append([]kvcell[K, T]{}, c.s...) // make non-nil copy c.mux.Unlock() for _, cell := range s { diff --git a/ftpio.go b/ftpio.go index 418f458..d713072 100644 --- a/ftpio.go +++ b/ftpio.go @@ -7,6 +7,7 @@ import ( "io/fs" "net/url" "path" + "strings" "sync" "time" @@ -19,24 +20,34 @@ var ( ) var ( - pwdmap map[string]string + pwdmap = map[string]string{} pwdmux sync.RWMutex ) -func PwdCache(ftpaddr string, conn *ftp.ServerConn) (pwd string) { - var ok bool +// FtpPwdPath return path from given URL concatenated with FTP +// current directory. It's used cache to avoid extra calls to +// FTP-server to get current directory for every call. +func FtpPwdPath(u *url.URL, conn *ftp.ServerConn) (fpath string) { + var ftpaddr = (&url.URL{ + Scheme: u.Scheme, + User: u.User, + Host: u.Host, + }).String() + pwdmux.RLock() - pwd, ok = pwdmap[ftpaddr] + var pwd, ok = pwdmap[ftpaddr] pwdmux.RUnlock() - if ok { - return + if !ok { + var err error + if pwd, err = conn.CurrentDir(); err == nil { + pwdmux.Lock() + pwdmap[ftpaddr] = pwd + pwdmux.Unlock() + } } - var err error - if pwd, err = conn.CurrentDir(); err == nil { - pwdmux.Lock() - pwdmap[ftpaddr] = pwd - pwdmux.Unlock() - return + fpath = path.Join(pwd, u.Path) + if strings.HasPrefix(fpath, "/") { + fpath = fpath[1:] } return } @@ -104,11 +115,7 @@ func (ff *FtpFile) Open(ftppath string) (err error) { if ff.conn, err = ftp.Dial(u.Host, ftp.DialWithTimeout(cfg.DialTimeout)); err != nil { return } - ff.path = path.Join(PwdCache((&url.URL{ - Scheme: u.Scheme, - User: u.User, - Host: u.Host, - }).String(), ff.conn), u.Path) + ff.path = FtpPwdPath(u, ff.conn) var pass, _ = u.User.Password() if err = ff.conn.Login(u.User.Username(), pass); err != nil { return diff --git a/io.go b/io.go index 53c97a2..ec5d6ba 100644 --- a/io.go +++ b/io.go @@ -137,8 +137,7 @@ func (pl *Profiles) ReadYaml(fname string) (err error) { var prf = pl.NewProfile("admin", "dag qus fly in the sky") prf.ID = 1 // set hidden files array to default predefined list - prf.Hidden = make([]string, len(DefHidden)) - copy(prf.Hidden, DefHidden) + prf.Hidden = append([]string{}, DefHidden...) // set default "home" share prf.Shares = []DiskPath{ {CPhome, CatNames[CPhome]}, diff --git a/opendisk.go b/opendisk.go index 9759d23..1cc2972 100644 --- a/opendisk.go +++ b/opendisk.go @@ -142,11 +142,10 @@ func StatFile(syspath string) (fi fs.FileInfo, err error) { if err = conn.Login(u.User.Username(), pass); err != nil { return } - var path = path.Join(PwdCache((&url.URL{ - Scheme: u.Scheme, - User: u.User, - Host: u.Host, - }).String(), conn), u.Path) + var path = FtpPwdPath(u, conn) + if strings.HasPrefix(path, "/") { + path = path[1:] + } var ent *ftp.Entry if ent, err = conn.GetEntry(path); err != nil { return @@ -223,11 +222,7 @@ func ReadDir(dir string) (ret []fs.FileInfo, err error) { if err = conn.Login(u.User.Username(), pass); err != nil { return } - var path = path.Join(PwdCache((&url.URL{ - Scheme: u.Scheme, - User: u.User, - Host: u.Host, - }).String(), conn), u.Path) + var path = FtpPwdPath(u, conn) var entries []*ftp.Entry if entries, err = conn.List(path); err != nil { return diff --git a/profile.go b/profile.go index 1a83f62..84cbb27 100644 --- a/profile.go +++ b/profile.go @@ -300,8 +300,7 @@ func (prf *Profile) FindLocal() { // ScanLocal scans paths from local roots list. func (prf *Profile) ScanLocal(session *Session) (ret []any, err error) { prf.mux.RLock() - var vfiles = make([]DiskPath, len(prf.Roots)) - copy(vfiles, prf.Roots) + var vfiles = append([]DiskPath{}, prf.Roots...) // make non-nil copy prf.mux.RUnlock() var dp DirProp @@ -323,8 +322,7 @@ func (prf *Profile) ScanLocal(session *Session) (ret []any, err error) { // ScanRemote scans paths at network destination. func (prf *Profile) ScanRemote(session *Session) (ret []any, err error) { prf.mux.RLock() - var vfiles = make([]DiskPath, len(prf.Remote)) - copy(vfiles, prf.Remote) + var vfiles = append([]DiskPath{}, prf.Remote...) // make non-nil copy prf.mux.RUnlock() var dp DirProp @@ -346,8 +344,7 @@ func (prf *Profile) ScanRemote(session *Session) (ret []any, err error) { // ScanShares scans actual shares from shares list. func (prf *Profile) ScanShares(session *Session) (ret []any, err error) { prf.mux.RLock() - var vfiles = make([]DiskPath, len(prf.Shares)) - copy(vfiles, prf.Shares) + var vfiles = append([]DiskPath{}, prf.Shares...) // make non-nil copy prf.mux.RUnlock() var dp DirProp