diff --git a/pkg/storage/file/fstore.go b/pkg/storage/file/fstore.go index 2eb51c9..5d3dcc7 100644 --- a/pkg/storage/file/fstore.go +++ b/pkg/storage/file/fstore.go @@ -4,7 +4,6 @@ import ( "bufio" "fmt" "io" - "io/ioutil" "os" "path/filepath" "sync" @@ -190,41 +189,33 @@ func (fs *Store) PurgeMessages(mailbox string) error { // VisitMailboxes accepts a function that will be called with the messages in each mailbox while it // continues to return true. func (fs *Store) VisitMailboxes(f func([]storage.Message) (cont bool)) error { - infos1, err := ioutil.ReadDir(fs.mailPath) + names1, err := readDirNames(fs.mailPath) if err != nil { return err } // Loop over level 1 directories - for _, inf1 := range infos1 { - if inf1.IsDir() { - l1 := inf1.Name() - infos2, err := ioutil.ReadDir(filepath.Join(fs.mailPath, l1)) + for _, name1 := range names1 { + names2, err := readDirNames(fs.mailPath, name1) + if err != nil { + return err + } + // Loop over level 2 directories + for _, name2 := range names2 { + names3, err := readDirNames(fs.mailPath, name1, name2) if err != nil { return err } - // Loop over level 2 directories - for _, inf2 := range infos2 { - if inf2.IsDir() { - l2 := inf2.Name() - infos3, err := ioutil.ReadDir(filepath.Join(fs.mailPath, l1, l2)) - if err != nil { - return err - } - // Loop over mailboxes - for _, inf3 := range infos3 { - if inf3.IsDir() { - mb := fs.mboxFromHash(inf3.Name()) - mb.RLock() - msgs, err := mb.getMessages() - mb.RUnlock() - if err != nil { - return err - } - if !f(msgs) { - return nil - } - } - } + // Loop over mailboxes + for _, name3 := range names3 { + mb := fs.mboxFromHash(name3) + mb.RLock() + msgs, err := mb.getMessages() + mb.RUnlock() + if err != nil { + return err + } + if !f(msgs) { + return nil } } } @@ -264,14 +255,14 @@ func (fs *Store) mboxFromHash(hash string) *mbox { } } -// getPooledReader pulls a buffered reader from the fs.bufReaderPool +// getPooledReader pulls a buffered reader from the fs.bufReaderPool. func (fs *Store) getPooledReader(r io.Reader) *bufio.Reader { br := fs.bufReaderPool.Get().(*bufio.Reader) br.Reset(r) return br } -// putPooledReader returns a buffered reader to the fs.bufReaderPool +// putPooledReader returns a buffered reader to the fs.bufReaderPool. func (fs *Store) putPooledReader(br *bufio.Reader) { fs.bufReaderPool.Put(br) } @@ -284,7 +275,16 @@ func generatePrefix(date time.Time) string { } // generateId adds a 4-digit unique number onto the end of the string -// returned by generatePrefix() +// returned by generatePrefix(). func generateID(date time.Time) string { return generatePrefix(date) + "-" + fmt.Sprintf("%04d", <-countChannel) } + +// readDirNames returns a slice of filenames in the specified directory or an error. +func readDirNames(elem ...string) ([]string, error) { + f, err := os.Open(filepath.Join(elem...)) + if err != nil { + return nil, err + } + return f.Readdirnames(0) +}