]> git.r.bdr.sh - rbdr/mobius/commitdiff
Convert hardcoded path separators to filepath.Join
authorJeff Halter <redacted>
Tue, 21 Jun 2022 05:21:28 +0000 (22:21 -0700)
committerJeff Halter <redacted>
Tue, 21 Jun 2022 05:21:28 +0000 (22:21 -0700)
cmd/mobius-hotline-server/main.go
hotline/file_path.go
hotline/file_transfer.go
hotline/file_types.go
hotline/file_wrapper.go
hotline/files.go
hotline/server.go
hotline/transaction_handlers_test.go

index bf41da1580093b55c89a6695485ad935da4a594f..63dc824a22591eb3a8e7858aff3a9cddf6b86403 100644 (file)
@@ -14,8 +14,8 @@ import (
        "math/rand"
        "net/http"
        "os"
+       "path/filepath"
        "runtime"
-       "strings"
        "time"
 )
 
@@ -71,12 +71,8 @@ func main() {
        defer func() { _ = l.Sync() }()
        logger := l.Sugar()
 
-       if !(strings.HasSuffix(*configDir, "/") || strings.HasSuffix(*configDir, "\\")) {
-               *configDir = *configDir + "/"
-       }
-
        if *init {
-               if _, err := os.Stat(*configDir + "/config.yaml"); os.IsNotExist(err) {
+               if _, err := os.Stat(filepath.Join(*configDir, "/config.yaml")); os.IsNotExist(err) {
                        if err := os.MkdirAll(*configDir, 0750); err != nil {
                                logger.Fatal(err)
                        }
@@ -92,7 +88,7 @@ func main() {
        }
 
        if _, err := os.Stat(*configDir); os.IsNotExist(err) {
-               logger.Fatalw("Configuration directory not found", "path", configDir)
+               logger.Fatalw("Configuration directory not found.  Correct the path or re-run with -init to generate initial config.", "path", configDir)
        }
 
        srv, err := hotline.NewServer(*configDir, *basePort, logger, &hotline.OSFileStore{})
@@ -176,17 +172,17 @@ func copyDir(src, dst string) error {
        }
        for _, dirEntry := range entries {
                if dirEntry.IsDir() {
-                       if err := os.MkdirAll(dst+"/"+dirEntry.Name(), 0777); err != nil {
+                       if err := os.MkdirAll(filepath.Join(dst, dirEntry.Name()), 0777); err != nil {
                                panic(err)
                        }
-                       subdirEntries, _ := cfgTemplate.ReadDir(src + "/" + dirEntry.Name())
+                       subdirEntries, _ := cfgTemplate.ReadDir(filepath.Join(src, dirEntry.Name()))
                        for _, subDirEntry := range subdirEntries {
-                               f, err := os.Create(dst + "/" + dirEntry.Name() + "/" + subDirEntry.Name())
+                               f, err := os.Create(filepath.Join(dst, dirEntry.Name(), subDirEntry.Name()))
                                if err != nil {
                                        return err
                                }
 
-                               srcFile, err := cfgTemplate.Open(src + "/" + dirEntry.Name() + "/" + subDirEntry.Name())
+                               srcFile, err := cfgTemplate.Open(filepath.Join(src, dirEntry.Name(), subDirEntry.Name()))
                                if err != nil {
                                        return err
                                }
@@ -197,12 +193,12 @@ func copyDir(src, dst string) error {
                                f.Close()
                        }
                } else {
-                       f, err := os.Create(dst + "/" + dirEntry.Name())
+                       f, err := os.Create(filepath.Join(dst, dirEntry.Name()))
                        if err != nil {
                                return err
                        }
 
-                       srcFile, err := cfgTemplate.Open(src + "/" + dirEntry.Name())
+                       srcFile, err := cfgTemplate.Open(filepath.Join(src, dirEntry.Name()))
                        if err != nil {
                                return err
                        }
index cdd95b9a33149f588378cec2c2014574dea4d108..c8fe652e878aa559e67bae2e9d3d59a1f89a4d35 100644 (file)
@@ -5,12 +5,10 @@ import (
        "encoding/binary"
        "errors"
        "io"
-       "path"
+       "path/filepath"
        "strings"
 )
 
-const pathSeparator = "/" // File path separator TODO: make configurable to support Windows
-
 // FilePathItem represents the file or directory portion of a delimited file path (e.g. foo and bar in "/foo/bar")
 // 00 00
 // 09
@@ -84,7 +82,7 @@ func (fp *FilePath) String() string {
                out = append(out, string(i.Name))
        }
 
-       return path.Join(out...)
+       return filepath.Join(out...)
 }
 
 func readPath(fileRoot string, filePath, fileName []byte) (fullPath string, err error) {
@@ -95,11 +93,11 @@ func readPath(fileRoot string, filePath, fileName []byte) (fullPath string, err
                }
        }
 
-       fullPath = path.Join(
+       fullPath = filepath.Join(
                "/",
                fileRoot,
                fp.String(),
-               path.Join("/", string(fileName)),
+               filepath.Join("/", string(fileName)),
        )
 
        return fullPath, nil
index 4a93390457c82a8e9c9f7b1f9f9e4f78f2f24db4..90dbbe669a2c9391afbb481f81f5c27bcded0eaa 100644 (file)
@@ -3,7 +3,7 @@ package hotline
 import (
        "encoding/binary"
        "fmt"
-       "strings"
+       "path/filepath"
 )
 
 // File transfer types
@@ -51,11 +51,12 @@ func (fu *folderUpload) FormattedPath() string {
        var pathSegments []string
        pathData := fu.FileNamePath
 
+       // TODO: implement scanner interface instead?
        for i := uint16(0); i < pathItemLen; i++ {
                segLen := pathData[2]
                pathSegments = append(pathSegments, string(pathData[3:3+segLen]))
                pathData = pathData[3+segLen:]
        }
 
-       return strings.Join(pathSegments, pathSeparator)
+       return filepath.Join(pathSegments...)
 }
index 216232384936bfcc535933235069e67f05b0b9a0..40b8374b4233a857a65a3c443933ad1a0a9eadff 100644 (file)
@@ -11,51 +11,55 @@ var defaultFileType = fileType{
 }
 
 var fileTypes = map[string]fileType{
-       "sit": {
+       ".sit": {
                TypeCode:    "SIT!",
                CreatorCode: "SIT!",
        },
-       "pdf": {
+       ".pdf": {
                TypeCode:    "PDF ",
                CreatorCode: "CARO",
        },
-       "gif": {
+       ".gif": {
                TypeCode:    "GIFf",
                CreatorCode: "ogle",
        },
-       "txt": {
+       ".txt": {
                TypeCode:    "TEXT",
                CreatorCode: "ttxt",
        },
-       "zip": {
+       ".zip": {
                TypeCode:    "ZIP ",
                CreatorCode: "SITx",
        },
-       "tgz": {
+       ".tgz": {
                TypeCode:    "Gzip",
                CreatorCode: "SITx",
        },
-       "hqx": {
+       ".hqx": {
                TypeCode:    "TEXT",
                CreatorCode: "SITx",
        },
-       "jpg": {
+       ".jpg": {
                TypeCode:    "JPEG",
                CreatorCode: "ogle",
        },
-       "img": {
+       ".jpeg": {
+               TypeCode:    "JPEG",
+               CreatorCode: "ogle",
+       },
+       ".img": {
                TypeCode:    "rohd",
                CreatorCode: "ddsk",
        },
-       "sea": {
+       ".sea": {
                TypeCode:    "APPL",
                CreatorCode: "aust",
        },
-       "mov": {
+       ".mov": {
                TypeCode:    "MooV",
                CreatorCode: "TVOD",
        },
-       "incomplete": { // Partial file upload
+       ".incomplete": { // Partial file upload
                TypeCode:    "HTft",
                CreatorCode: "HTLC",
        },
index 3773e79812204343e24e6e90958517b085218895..2ad76f48539726d3e8bf9fed18971833c957b76f 100644 (file)
@@ -8,13 +8,13 @@ import (
        "io/fs"
        "os"
        "path"
-       "strings"
+       "path/filepath"
 )
 
 const (
        incompleteFileSuffix = ".incomplete"
-       infoForkNameTemplate = "%s.info_%s" // template string for info fork filenames
-       rsrcForkNameTemplate = "%s.rsrc_%s" // template string for resource fork filenames
+       infoForkNameTemplate = ".info_%s" // template string for info fork filenames
+       rsrcForkNameTemplate = ".rsrc_%s" // template string for resource fork filenames
 )
 
 // fileWrapper encapsulates the data, info, and resource forks of a Hotline file and provides methods to manage the files.
@@ -33,18 +33,17 @@ type fileWrapper struct {
 }
 
 func newFileWrapper(fs FileStore, path string, dataOffset int64) (*fileWrapper, error) {
-       pathSegs := strings.Split(path, pathSeparator)
-       dir := strings.Join(pathSegs[:len(pathSegs)-1], pathSeparator)
-       fName := pathSegs[len(pathSegs)-1]
+       dir := filepath.Dir(path)
+       fName := filepath.Base(path)
        f := fileWrapper{
                fs:             fs,
                name:           fName,
                path:           dir,
                dataPath:       path,
                dataOffset:     dataOffset,
-               rsrcPath:       fmt.Sprintf(rsrcForkNameTemplate, dir+"/", fName),
-               infoPath:       fmt.Sprintf(infoForkNameTemplate, dir+"/", fName),
-               incompletePath: dir + "/" + fName + incompleteFileSuffix,
+               rsrcPath:       filepath.Join(dir, fmt.Sprintf(rsrcForkNameTemplate, fName)),
+               infoPath:       filepath.Join(dir, fmt.Sprintf(infoForkNameTemplate, fName)),
+               incompletePath: filepath.Join(dir, fName+incompleteFileSuffix),
                ffo:            &flattenedFileObject{},
        }
 
@@ -100,11 +99,11 @@ func (f *fileWrapper) incompleteDataName() string {
 }
 
 func (f *fileWrapper) rsrcForkName() string {
-       return fmt.Sprintf(rsrcForkNameTemplate, "", f.name)
+       return fmt.Sprintf(rsrcForkNameTemplate, f.name)
 }
 
 func (f *fileWrapper) infoForkName() string {
-       return fmt.Sprintf(infoForkNameTemplate, "", f.name)
+       return fmt.Sprintf(infoForkNameTemplate, f.name)
 }
 
 func (f *fileWrapper) creatorCode() []byte {
index b66580fcfef1d5e119823ce842406c2935f54e82..dc196536d8b7abfc870c07f96ecb0dbc2a48eef5 100644 (file)
@@ -10,17 +10,9 @@ import (
        "strings"
 )
 
-func downcaseFileExtension(filename string) string {
-       splitStr := strings.Split(filename, ".")
-       ext := strings.ToLower(
-               splitStr[len(splitStr)-1],
-       )
-
-       return ext
-}
-
-func fileTypeFromFilename(fn string) fileType {
-       ft, ok := fileTypes[downcaseFileExtension(fn)]
+func fileTypeFromFilename(filename string) fileType {
+       fileExt := strings.ToLower(filepath.Ext(filename))
+       ft, ok := fileTypes[fileExt]
        if ok {
                return ft
        }
@@ -38,8 +30,8 @@ func fileTypeFromInfo(info fs.FileInfo) (ft fileType, err error) {
        return ft, nil
 }
 
-func getFileNameList(filePath string) (fields []Field, err error) {
-       files, err := os.ReadDir(filePath)
+func getFileNameList(path string) (fields []Field, err error) {
+       files, err := os.ReadDir(path)
        if err != nil {
                return fields, nil
        }
@@ -59,12 +51,12 @@ func getFileNameList(filePath string) (fields []Field, err error) {
                }
 
                if fileInfo.Mode()&os.ModeSymlink != 0 {
-                       resolvedPath, err := os.Readlink(filePath + "/" + file.Name())
+                       resolvedPath, err := os.Readlink(filepath.Join(path, file.Name()))
                        if err != nil {
                                return fields, err
                        }
 
-                       rFile, err := os.Stat(filePath + "/" + resolvedPath)
+                       rFile, err := os.Stat(filepath.Join(path, resolvedPath))
                        if errors.Is(err, os.ErrNotExist) {
                                continue
                        }
@@ -73,7 +65,7 @@ func getFileNameList(filePath string) (fields []Field, err error) {
                        }
 
                        if rFile.IsDir() {
-                               dir, err := ioutil.ReadDir(filePath + "/" + file.Name())
+                               dir, err := ioutil.ReadDir(filepath.Join(path, file.Name()))
                                if err != nil {
                                        return fields, err
                                }
@@ -95,7 +87,7 @@ func getFileNameList(filePath string) (fields []Field, err error) {
                        }
 
                } else if file.IsDir() {
-                       dir, err := ioutil.ReadDir(filePath + "/" + file.Name())
+                       dir, err := ioutil.ReadDir(filepath.Join(path, file.Name()))
                        if err != nil {
                                return fields, err
                        }
@@ -116,7 +108,7 @@ func getFileNameList(filePath string) (fields []Field, err error) {
                                continue
                        }
 
-                       hlFile, err := newFileWrapper(&OSFileStore{}, filePath+"/"+file.Name(), 0)
+                       hlFile, err := newFileWrapper(&OSFileStore{}, path+"/"+file.Name(), 0)
                        if err != nil {
                                return nil, err
                        }
index 9df89f2b219ac0a7f24e57c48cbc8a6b2a967cb0..9ffd27257340d41554b6d67ab22088f9650553b7 100644 (file)
@@ -17,7 +17,6 @@ import (
        "math/rand"
        "net"
        "os"
-       "path"
        "path/filepath"
        "runtime/debug"
        "strings"
@@ -227,28 +226,28 @@ func NewServer(configDir string, netPort int, logger *zap.SugaredLogger, FS File
                return nil, err
        }
 
-       server.Agreement, err = os.ReadFile(configDir + agreementFile)
+       server.Agreement, err = os.ReadFile(filepath.Join(configDir, agreementFile))
        if err != nil {
                return nil, err
        }
 
-       if server.FlatNews, err = os.ReadFile(configDir + "MessageBoard.txt"); err != nil {
+       if server.FlatNews, err = os.ReadFile(filepath.Join(configDir, "MessageBoard.txt")); err != nil {
                return nil, err
        }
 
-       if err := server.loadThreadedNews(configDir + "ThreadedNews.yaml"); err != nil {
+       if err := server.loadThreadedNews(filepath.Join(configDir, "ThreadedNews.yaml")); err != nil {
                return nil, err
        }
 
-       if err := server.loadConfig(configDir + "config.yaml"); err != nil {
+       if err := server.loadConfig(filepath.Join(configDir, "config.yaml")); err != nil {
                return nil, err
        }
 
-       if err := server.loadAccounts(configDir + "Users/"); err != nil {
+       if err := server.loadAccounts(filepath.Join(configDir, "Users/")); err != nil {
                return nil, err
        }
 
-       server.Config.FileRoot = configDir + "Files/"
+       server.Config.FileRoot = filepath.Join(configDir, "Files")
 
        *server.NextGuestID = 1
 
@@ -329,7 +328,7 @@ func (s *Server) writeThreadedNews() error {
                return err
        }
        err = ioutil.WriteFile(
-               s.ConfigDir+"ThreadedNews.yaml",
+               filepath.Join(s.ConfigDir, "ThreadedNews.yaml"),
                out,
                0666,
        )
@@ -379,7 +378,7 @@ func (s *Server) NewUser(login, name, password string, access []byte) error {
        }
        s.Accounts[login] = &account
 
-       return s.FS.WriteFile(s.ConfigDir+"Users/"+login+".yaml", out, 0666)
+       return s.FS.WriteFile(filepath.Join(s.ConfigDir, "Users", login+".yaml"), out, 0666)
 }
 
 func (s *Server) UpdateUser(login, newLogin, name, password string, access []byte) error {
@@ -388,7 +387,7 @@ func (s *Server) UpdateUser(login, newLogin, name, password string, access []byt
 
        // update renames the user login
        if login != newLogin {
-               err := os.Rename(s.ConfigDir+"Users/"+login+".yaml", s.ConfigDir+"Users/"+newLogin+".yaml")
+               err := os.Rename(filepath.Join(s.ConfigDir, "Users", login+".yaml"), filepath.Join(s.ConfigDir, "Users", newLogin+".yaml"))
                if err != nil {
                        return err
                }
@@ -405,7 +404,8 @@ func (s *Server) UpdateUser(login, newLogin, name, password string, access []byt
        if err != nil {
                return err
        }
-       if err := os.WriteFile(s.ConfigDir+"Users/"+newLogin+".yaml", out, 0666); err != nil {
+
+       if err := os.WriteFile(filepath.Join(s.ConfigDir, "Users", newLogin+".yaml"), out, 0666); err != nil {
                return err
        }
 
@@ -419,7 +419,7 @@ func (s *Server) DeleteUser(login string) error {
 
        delete(s.Accounts, login)
 
-       return s.FS.Remove(s.ConfigDir + "Users/" + login + ".yaml")
+       return s.FS.Remove(filepath.Join(s.ConfigDir, "Users", login+".yaml"))
 }
 
 func (s *Server) connectedUsers() []Field {
@@ -455,7 +455,7 @@ func (s *Server) loadThreadedNews(threadedNewsPath string) error {
 
 // loadAccounts loads account data from disk
 func (s *Server) loadAccounts(userDir string) error {
-       matches, err := filepath.Glob(path.Join(userDir, "*.yaml"))
+       matches, err := filepath.Glob(filepath.Join(userDir, "*.yaml"))
        if err != nil {
                return err
        }
@@ -1059,8 +1059,8 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                        )
 
                        if fu.IsFolder == [2]byte{0, 1} {
-                               if _, err := os.Stat(dstPath + "/" + fu.FormattedPath()); os.IsNotExist(err) {
-                                       if err := os.Mkdir(dstPath+"/"+fu.FormattedPath(), 0777); err != nil {
+                               if _, err := os.Stat(filepath.Join(dstPath, fu.FormattedPath())); os.IsNotExist(err) {
+                                       if err := os.Mkdir(filepath.Join(dstPath, fu.FormattedPath()), 0777); err != nil {
                                                return err
                                        }
                                }
@@ -1073,7 +1073,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                                nextAction := dlFldrActionSendFile
 
                                // Check if we have the full file already.  If so, send dlFldrAction_NextFile to client to skip.
-                               _, err = os.Stat(dstPath + "/" + fu.FormattedPath())
+                               _, err = os.Stat(filepath.Join(dstPath, fu.FormattedPath()))
                                if err != nil && !errors.Is(err, fs.ErrNotExist) {
                                        return err
                                }
@@ -1082,7 +1082,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                                }
 
                                //  Check if we have a partial file already.  If so, send dlFldrAction_ResumeFile to client to resume upload.
-                               incompleteFile, err := os.Stat(dstPath + "/" + fu.FormattedPath() + incompleteFileSuffix)
+                               incompleteFile, err := os.Stat(filepath.Join(dstPath, fu.FormattedPath()+incompleteFileSuffix))
                                if err != nil && !errors.Is(err, fs.ErrNotExist) {
                                        return err
                                }
@@ -1135,7 +1135,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                                                return err
                                        }
 
-                                       filePath := dstPath + "/" + fu.FormattedPath()
+                                       filePath := filepath.Join(dstPath, fu.FormattedPath())
 
                                        hlFile, err := newFileWrapper(s.FS, filePath, 0)
                                        if err != nil {
index ebb4a95c303f7e43980e6e32ec4f798fff5df747..0e2c9499c62fcddac2a8ce4ae31dd98be25823e1 100644 (file)
@@ -7,6 +7,7 @@ import (
        "io/fs"
        "math/rand"
        "os"
+       "path/filepath"
        "strings"
        "testing"
        "time"
@@ -630,7 +631,7 @@ func TestHandleGetFileInfo(t *testing.T) {
                                                Config: &Config{
                                                        FileRoot: func() string {
                                                                path, _ := os.Getwd()
-                                                               return path + "/test/config/Files"
+                                                               return filepath.Join(path, "/test/config/Files")
                                                        }(),
                                                },
                                        },