aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hotline/account.go1
-rw-r--r--hotline/client_conn.go7
-rw-r--r--hotline/file_transfer.go4
-rw-r--r--hotline/server.go10
-rw-r--r--hotline/server_test.go11
-rw-r--r--internal/mobius/transaction_handlers.go52
-rw-r--r--internal/mobius/transaction_handlers_test.go16
7 files changed, 58 insertions, 43 deletions
diff --git a/hotline/account.go b/hotline/account.go
index 7f770b1..526eb05 100644
--- a/hotline/account.go
+++ b/hotline/account.go
@@ -15,6 +15,7 @@ type Account struct {
Name string `yaml:"Name"`
Password string `yaml:"Password"`
Access AccessBitmap `yaml:"Access,flow"`
+ FileRoot string `yaml:"FileRoot"`
readOffset int // Internal offset to track read progress
}
diff --git a/hotline/client_conn.go b/hotline/client_conn.go
index 060a2b9..d324591 100644
--- a/hotline/client_conn.go
+++ b/hotline/client_conn.go
@@ -42,6 +42,13 @@ type ClientConn struct {
mu sync.RWMutex
}
+func (cc *ClientConn) FileRoot() string {
+ if cc.Account.FileRoot != "" {
+ return cc.Account.FileRoot
+ }
+ return cc.Server.Config.FileRoot
+}
+
type ClientFileTransferMgr struct {
transfers map[FileTransferType]map[FileTransferID]*FileTransfer
diff --git a/hotline/file_transfer.go b/hotline/file_transfer.go
index 806466b..12725db 100644
--- a/hotline/file_transfer.go
+++ b/hotline/file_transfer.go
@@ -87,6 +87,7 @@ func (ftm *MemFileTransferMgr) Delete(id FileTransferID) {
}
type FileTransfer struct {
+ FileRoot string
FileName []byte
FilePath []byte
RefNum [4]byte
@@ -116,9 +117,10 @@ func (wc *WriteCounter) Write(p []byte) (int, error) {
return n, nil
}
-func (cc *ClientConn) NewFileTransfer(transferType FileTransferType, fileName, filePath, size []byte) *FileTransfer {
+func (cc *ClientConn) NewFileTransfer(transferType FileTransferType, fileroot string, fileName, filePath, size []byte) *FileTransfer {
ft := &FileTransfer{
FileName: fileName,
+ FileRoot: fileroot,
FilePath: filePath,
Type: transferType,
TransferSize: size,
diff --git a/hotline/server.go b/hotline/server.go
index 04ac8c7..c4d8f7f 100644
--- a/hotline/server.go
+++ b/hotline/server.go
@@ -526,7 +526,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
"Name", string(fileTransfer.ClientConn.UserName),
)
- fullPath, err := ReadPath(s.Config.FileRoot, fileTransfer.FilePath, fileTransfer.FileName)
+ fullPath, err := ReadPath(fileTransfer.FileRoot, fileTransfer.FilePath, fileTransfer.FileName)
if err != nil {
return err
}
@@ -534,7 +534,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
switch fileTransfer.Type {
case BannerDownload:
if _, err := io.Copy(rwc, bytes.NewBuffer(s.Banner)); err != nil {
- return fmt.Errorf("error sending Banner: %w", err)
+ return fmt.Errorf("banner download: %w", err)
}
case FileDownload:
s.Stats.Increment(StatDownloadCounter, StatDownloadsInProgress)
@@ -555,7 +555,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
err = UploadHandler(rwc, fullPath, fileTransfer, s.FS, rLogger, s.Config.PreserveResourceForks)
if err != nil {
- return fmt.Errorf("file upload error: %w", err)
+ return fmt.Errorf("file upload: %w", err)
}
case FolderDownload:
@@ -566,7 +566,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
err = DownloadFolderHandler(rwc, fullPath, fileTransfer, s.FS, rLogger, s.Config.PreserveResourceForks)
if err != nil {
- return fmt.Errorf("file upload error: %w", err)
+ return fmt.Errorf("folder download: %w", err)
}
case FolderUpload:
@@ -584,7 +584,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
err = UploadFolderHandler(rwc, fullPath, fileTransfer, s.FS, rLogger, s.Config.PreserveResourceForks)
if err != nil {
- return fmt.Errorf("file upload error: %w", err)
+ return fmt.Errorf("folder upload: %w", err)
}
}
return nil
diff --git a/hotline/server_test.go b/hotline/server_test.go
index c3d38da..d0e2372 100644
--- a/hotline/server_test.go
+++ b/hotline/server_test.go
@@ -99,12 +99,7 @@ func TestServer_handleFileTransfer(t *testing.T) {
{
name: "file download",
fields: fields{
- FS: &OSFileStore{},
- Config: Config{
- FileRoot: func() string {
- path, _ := os.Getwd()
- return path + "/test/config/Files"
- }()},
+ FS: &OSFileStore{},
Logger: NewTestLogger(),
Stats: NewStats(),
FileTransferMgr: &MemFileTransferMgr{
@@ -114,6 +109,10 @@ func TestServer_handleFileTransfer(t *testing.T) {
Type: FileDownload,
FileName: []byte("testfile-8b"),
FilePath: []byte{},
+ FileRoot: func() string {
+ path, _ := os.Getwd()
+ return path + "/test/config/Files"
+ }(),
ClientConn: &ClientConn{
Account: &Account{
Login: "foo",
diff --git a/internal/mobius/transaction_handlers.go b/internal/mobius/transaction_handlers.go
index 399a8c0..759ee66 100644
--- a/internal/mobius/transaction_handlers.go
+++ b/internal/mobius/transaction_handlers.go
@@ -204,7 +204,7 @@ func HandleGetFileInfo(cc *hotline.ClientConn, t *hotline.Transaction) (res []ho
fileName := t.GetField(hotline.FieldFileName).Data
filePath := t.GetField(hotline.FieldFilePath).Data
- fullFilePath, err := hotline.ReadPath(cc.Server.Config.FileRoot, filePath, fileName)
+ fullFilePath, err := hotline.ReadPath(cc.FileRoot(), filePath, fileName)
if err != nil {
return res
}
@@ -253,7 +253,7 @@ func HandleSetFileInfo(cc *hotline.ClientConn, t *hotline.Transaction) (res []ho
fileName := t.GetField(hotline.FieldFileName).Data
filePath := t.GetField(hotline.FieldFilePath).Data
- fullFilePath, err := hotline.ReadPath(cc.Server.Config.FileRoot, filePath, fileName)
+ fullFilePath, err := hotline.ReadPath(cc.FileRoot(), filePath, fileName)
if err != nil {
return res
}
@@ -292,7 +292,7 @@ func HandleSetFileInfo(cc *hotline.ClientConn, t *hotline.Transaction) (res []ho
}
}
- fullNewFilePath, err := hotline.ReadPath(cc.Server.Config.FileRoot, filePath, t.GetField(hotline.FieldFileNewName).Data)
+ fullNewFilePath, err := hotline.ReadPath(cc.FileRoot(), filePath, t.GetField(hotline.FieldFileNewName).Data)
if err != nil {
return nil
}
@@ -314,7 +314,7 @@ func HandleSetFileInfo(cc *hotline.ClientConn, t *hotline.Transaction) (res []ho
if !cc.Authorize(hotline.AccessRenameFile) {
return cc.NewErrReply(t, "You are not allowed to rename files.")
}
- fileDir, err := hotline.ReadPath(cc.Server.Config.FileRoot, filePath, []byte{})
+ fileDir, err := hotline.ReadPath(cc.FileRoot(), filePath, []byte{})
if err != nil {
return nil
}
@@ -346,7 +346,7 @@ func HandleDeleteFile(cc *hotline.ClientConn, t *hotline.Transaction) (res []hot
fileName := t.GetField(hotline.FieldFileName).Data
filePath := t.GetField(hotline.FieldFilePath).Data
- fullFilePath, err := hotline.ReadPath(cc.Server.Config.FileRoot, filePath, fileName)
+ fullFilePath, err := hotline.ReadPath(cc.FileRoot(), filePath, fileName)
if err != nil {
return res
}
@@ -384,12 +384,12 @@ func HandleDeleteFile(cc *hotline.ClientConn, t *hotline.Transaction) (res []hot
func HandleMoveFile(cc *hotline.ClientConn, t *hotline.Transaction) (res []hotline.Transaction) {
fileName := string(t.GetField(hotline.FieldFileName).Data)
- filePath, err := hotline.ReadPath(cc.Server.Config.FileRoot, t.GetField(hotline.FieldFilePath).Data, t.GetField(hotline.FieldFileName).Data)
+ filePath, err := hotline.ReadPath(cc.FileRoot(), t.GetField(hotline.FieldFilePath).Data, t.GetField(hotline.FieldFileName).Data)
if err != nil {
return res
}
- fileNewPath, err := hotline.ReadPath(cc.Server.Config.FileRoot, t.GetField(hotline.FieldFileNewPath).Data, nil)
+ fileNewPath, err := hotline.ReadPath(cc.FileRoot(), t.GetField(hotline.FieldFileNewPath).Data, nil)
if err != nil {
return res
}
@@ -446,7 +446,7 @@ func HandleNewFolder(cc *hotline.ClientConn, t *hotline.Transaction) (res []hotl
subPath = filepath.Join("/", subPath, string(pathItem.Name))
}
}
- newFolderPath := path.Join(cc.Server.Config.FileRoot, subPath, folderName)
+ newFolderPath := path.Join(cc.FileRoot(), subPath, folderName)
newFolderPath, err := txtDecoder.String(newFolderPath)
if err != nil {
return res
@@ -1279,7 +1279,7 @@ func HandleDownloadFile(cc *hotline.ClientConn, t *hotline.Transaction) (res []h
dataOffset = int64(binary.BigEndian.Uint32(frd.ForkInfoList[0].DataSize[:]))
}
- fullFilePath, err := hotline.ReadPath(cc.Server.Config.FileRoot, filePath, fileName)
+ fullFilePath, err := hotline.ReadPath(cc.FileRoot(), filePath, fileName)
if err != nil {
return res
}
@@ -1291,9 +1291,14 @@ func HandleDownloadFile(cc *hotline.ClientConn, t *hotline.Transaction) (res []h
xferSize := hlFile.Ffo.TransferSize(0)
- ft := cc.NewFileTransfer(hotline.FileDownload, fileName, filePath, xferSize)
+ ft := cc.NewFileTransfer(
+ hotline.FileDownload,
+ cc.FileRoot(),
+ fileName,
+ filePath,
+ xferSize,
+ )
- // TODO: refactor to remove this
if resumeData != nil {
var frd hotline.FileResumeData
if err := frd.UnmarshalBinary(t.GetField(hotline.FieldFileResumeData).Data); err != nil {
@@ -1326,26 +1331,26 @@ func HandleDownloadFolder(cc *hotline.ClientConn, t *hotline.Transaction) (res [
return cc.NewErrReply(t, "You are not allowed to download folders.")
}
- fullFilePath, err := hotline.ReadPath(cc.Server.Config.FileRoot, t.GetField(hotline.FieldFilePath).Data, t.GetField(hotline.FieldFileName).Data)
+ fullFilePath, err := hotline.ReadPath(cc.FileRoot(), t.GetField(hotline.FieldFilePath).Data, t.GetField(hotline.FieldFileName).Data)
if err != nil {
- return res
+ return nil
}
transferSize, err := hotline.CalcTotalSize(fullFilePath)
if err != nil {
- return res
+ return nil
}
itemCount, err := hotline.CalcItemCount(fullFilePath)
if err != nil {
- return res
+ return nil
}
- fileTransfer := cc.NewFileTransfer(hotline.FolderDownload, t.GetField(hotline.FieldFileName).Data, t.GetField(hotline.FieldFilePath).Data, transferSize)
+ fileTransfer := cc.NewFileTransfer(hotline.FolderDownload, cc.FileRoot(), t.GetField(hotline.FieldFileName).Data, t.GetField(hotline.FieldFilePath).Data, transferSize)
var fp hotline.FilePath
_, err = fp.Write(t.GetField(hotline.FieldFilePath).Data)
if err != nil {
- return res
+ return nil
}
res = append(res, cc.NewReply(t,
@@ -1380,6 +1385,7 @@ func HandleUploadFolder(cc *hotline.ClientConn, t *hotline.Transaction) (res []h
}
fileTransfer := cc.NewFileTransfer(hotline.FolderUpload,
+ cc.FileRoot(),
t.GetField(hotline.FieldFileName).Data,
t.GetField(hotline.FieldFilePath).Data,
t.GetField(hotline.FieldTransferSize).Data,
@@ -1420,7 +1426,7 @@ func HandleUploadFile(cc *hotline.ClientConn, t *hotline.Transaction) (res []hot
return cc.NewErrReply(t, fmt.Sprintf("Cannot accept upload of the file \"%v\" because you are only allowed to upload to the \"Uploads\" folder.", string(fileName)))
}
}
- fullFilePath, err := hotline.ReadPath(cc.Server.Config.FileRoot, filePath, fileName)
+ fullFilePath, err := hotline.ReadPath(cc.FileRoot(), filePath, fileName)
if err != nil {
return res
}
@@ -1429,7 +1435,7 @@ func HandleUploadFile(cc *hotline.ClientConn, t *hotline.Transaction) (res []hot
return cc.NewErrReply(t, fmt.Sprintf("Cannot accept upload because there is already a file named \"%v\". Try choosing a different Name.", string(fileName)))
}
- ft := cc.NewFileTransfer(hotline.FileUpload, fileName, filePath, transferSize)
+ ft := cc.NewFileTransfer(hotline.FileUpload, cc.FileRoot(), fileName, filePath, transferSize)
replyT := cc.NewReply(t, hotline.NewField(hotline.FieldRefNum, ft.RefNum[:]))
@@ -1509,7 +1515,7 @@ func HandleKeepAlive(cc *hotline.ClientConn, t *hotline.Transaction) (res []hotl
func HandleGetFileNameList(cc *hotline.ClientConn, t *hotline.Transaction) (res []hotline.Transaction) {
fullPath, err := hotline.ReadPath(
- cc.Server.Config.FileRoot,
+ cc.FileRoot(),
t.GetField(hotline.FieldFilePath).Data,
nil,
)
@@ -1756,12 +1762,12 @@ func HandleMakeAlias(cc *hotline.ClientConn, t *hotline.Transaction) (res []hotl
filePath := t.GetField(hotline.FieldFilePath).Data
fileNewPath := t.GetField(hotline.FieldFileNewPath).Data
- fullFilePath, err := hotline.ReadPath(cc.Server.Config.FileRoot, filePath, fileName)
+ fullFilePath, err := hotline.ReadPath(cc.FileRoot(), filePath, fileName)
if err != nil {
return res
}
- fullNewFilePath, err := hotline.ReadPath(cc.Server.Config.FileRoot, fileNewPath, fileName)
+ fullNewFilePath, err := hotline.ReadPath(cc.FileRoot(), fileNewPath, fileName)
if err != nil {
return res
}
@@ -1783,7 +1789,7 @@ func HandleMakeAlias(cc *hotline.ClientConn, t *hotline.Transaction) (res []hotl
// 107 FieldRefNum Used later for transfer
// 108 FieldTransferSize Size of data to be downloaded
func HandleDownloadBanner(cc *hotline.ClientConn, t *hotline.Transaction) (res []hotline.Transaction) {
- ft := cc.NewFileTransfer(hotline.BannerDownload, []byte{}, []byte{}, make([]byte, 4))
+ ft := cc.NewFileTransfer(hotline.BannerDownload, "", []byte{}, []byte{}, make([]byte, 4))
binary.BigEndian.PutUint32(ft.TransferSize, uint32(len(cc.Server.Banner)))
return append(res, cc.NewReply(t,
diff --git a/internal/mobius/transaction_handlers_test.go b/internal/mobius/transaction_handlers_test.go
index 63d2946..26ea950 100644
--- a/internal/mobius/transaction_handlers_test.go
+++ b/internal/mobius/transaction_handlers_test.go
@@ -782,7 +782,8 @@ func TestHandleGetFileInfo(t *testing.T) {
name: "returns expected fields when a valid file is requested",
args: args{
cc: &hotline.ClientConn{
- ID: [2]byte{0x00, 0x01},
+ ID: [2]byte{0, 1},
+ Account: &hotline.Account{},
Server: &hotline.Server{
FS: &hotline.OSFileStore{},
Config: hotline.Config{
@@ -2629,14 +2630,13 @@ func TestHandleGetFileNameList(t *testing.T) {
name: "with file root",
args: args{
cc: &hotline.ClientConn{
- Server: &hotline.Server{
- Config: hotline.Config{
- FileRoot: func() string {
- path, _ := os.Getwd()
- return filepath.Join(path, "/test/config/Files/getFileNameListTestDir")
- }(),
- },
+ Account: &hotline.Account{
+ FileRoot: func() string {
+ path, _ := os.Getwd()
+ return filepath.Join(path, "/test/config/Files/getFileNameListTestDir")
+ }(),
},
+ Server: &hotline.Server{},
},
t: hotline.NewTransaction(
hotline.TranGetFileNameList, [2]byte{0, 1},