platform_common.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. // Copyright (C) 2022 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at https://mozilla.org/MPL/2.0/.
  6. package fs
  7. import (
  8. "os/user"
  9. "strconv"
  10. "github.com/syncthing/syncthing/lib/protocol"
  11. )
  12. // unixPlatformData is used on all platforms, because apart from being the
  13. // implementation for BasicFilesystem on Unixes it's also the implementation
  14. // in fakeFS.
  15. func unixPlatformData(fs Filesystem, name string) (protocol.PlatformData, error) {
  16. stat, err := fs.Lstat(name)
  17. if err != nil {
  18. return protocol.PlatformData{}, err
  19. }
  20. ownerUID := stat.Owner()
  21. ownerName := ""
  22. if u, err := user.LookupId(strconv.Itoa(ownerUID)); err == nil && u.Username != "" {
  23. ownerName = u.Username
  24. } else if ownerUID == 0 {
  25. // We couldn't look up a name, but UID zero should be "root". This
  26. // fixup works around the (unlikely) situation where the ownership
  27. // is 0:0 but we can't look up a name for either uid zero or gid
  28. // zero. If that were the case we'd return a zero PlatformData which
  29. // wouldn't get serialized over the wire and the other side would
  30. // assume a lack of ownership info...
  31. ownerName = "root"
  32. }
  33. groupID := stat.Group()
  34. groupName := ""
  35. if g, err := user.LookupGroupId(strconv.Itoa(groupID)); err == nil && g.Name != "" {
  36. groupName = g.Name
  37. } else if groupID == 0 {
  38. groupName = "root"
  39. }
  40. return protocol.PlatformData{
  41. Unix: &protocol.UnixData{
  42. OwnerName: ownerName,
  43. GroupName: groupName,
  44. UID: ownerUID,
  45. GID: groupID,
  46. },
  47. }, nil
  48. }