]> git.r.bdr.sh - rbdr/mobius/blobdiff - hotline/server.go
Fix some data races
[rbdr/mobius] / hotline / server.go
index 0828385dc2ed9027f13075605af634ee0a399490..cf022fc9f9e3a2d3a6649253f1256e371cb079a3 100644 (file)
@@ -359,6 +359,38 @@ func (s *Server) NewUser(login, name, password string, access []byte) error {
        return FS.WriteFile(s.ConfigDir+"Users/"+login+".yaml", out, 0666)
 }
 
+func (s *Server) UpdateUser(login, newLogin, name, password string, access []byte) error {
+       s.mux.Lock()
+       defer s.mux.Unlock()
+
+       fmt.Printf("login: %v, newLogin: %v: ", login, newLogin)
+
+       // update renames the user login
+       if login != newLogin {
+               err := os.Rename(s.ConfigDir+"Users/"+login+".yaml", s.ConfigDir+"Users/"+newLogin+".yaml")
+               if err != nil {
+                       return err
+               }
+               s.Accounts[newLogin] = s.Accounts[login]
+               delete(s.Accounts, login)
+       }
+
+       account := s.Accounts[newLogin]
+       account.Access = &access
+       account.Name = name
+       account.Password = password
+
+       out, err := yaml.Marshal(&account)
+       if err != nil {
+               return err
+       }
+       if err := os.WriteFile(s.ConfigDir+"Users/"+newLogin+".yaml", out, 0666); err != nil {
+               return err
+       }
+
+       return nil
+}
+
 // DeleteUser deletes the user account
 func (s *Server) DeleteUser(login string) error {
        s.mux.Lock()
@@ -614,28 +646,42 @@ const dlFldrActionNextFile = 3
 // handleFileTransfer receives a client net.Conn from the file transfer server, performs the requested transfer type, then closes the connection
 func (s *Server) handleFileTransfer(conn io.ReadWriteCloser) error {
        defer func() {
+
                if err := conn.Close(); err != nil {
                        s.Logger.Errorw("error closing connection", "error", err)
                }
        }()
 
+       defer func() {
+               if r := recover(); r != nil {
+                       fmt.Println("stacktrace from panic: \n" + string(debug.Stack()))
+                       s.Logger.Errorw("PANIC", "err", r, "trace", string(debug.Stack()))
+               }
+       }()
+
        txBuf := make([]byte, 16)
-       _, err := conn.Read(txBuf)
-       if err != nil {
+       if _, err := io.ReadFull(conn, txBuf); err != nil {
                return err
        }
 
        var t transfer
-       _, err = t.Write(txBuf)
-       if err != nil {
+       if _, err := t.Write(txBuf); err != nil {
                return err
        }
 
        transferRefNum := binary.BigEndian.Uint32(t.ReferenceNumber[:])
-       fileTransfer := s.FileTransfers[transferRefNum]
+       defer func() {
+               s.mux.Lock()
+               delete(s.FileTransfers, transferRefNum)
+               s.mux.Unlock()
+       }()
 
-       // delete single use transferRefNum
-       delete(s.FileTransfers, transferRefNum)
+       s.mux.Lock()
+       fileTransfer, ok := s.FileTransfers[transferRefNum]
+       s.mux.Unlock()
+       if !ok {
+               return errors.New("invalid transaction ID")
+       }
 
        switch fileTransfer.Type {
        case FileDownload:
@@ -656,9 +702,11 @@ func (s *Server) handleFileTransfer(conn io.ReadWriteCloser) error {
 
                s.Logger.Infow("File download started", "filePath", fullFilePath, "transactionRef", fileTransfer.ReferenceNumber)
 
-               // Start by sending flat file object to client
-               if _, err := conn.Write(ffo.BinaryMarshal()); err != nil {
-                       return err
+               if fileTransfer.options == nil {
+                       // Start by sending flat file object to client
+                       if _, err := conn.Write(ffo.BinaryMarshal()); err != nil {
+                               return err
+                       }
                }
 
                file, err := FS.Open(fullFilePath)