config_unix.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. //go:build aix || dragonfly || freebsd || (js && wasm) || nacl || linux || netbsd || openbsd || solaris
  2. package userdirs
  3. import (
  4. "bufio"
  5. "io"
  6. "os"
  7. "strings"
  8. "github.com/adrg/xdg/internal/pathutil"
  9. )
  10. // ParseConfigFile parses the user directories config file at the
  11. // specified location.
  12. func ParseConfigFile(name string) (*Directories, error) {
  13. f, err := os.Open(name)
  14. if err != nil {
  15. return nil, err
  16. }
  17. defer f.Close()
  18. return ParseConfig(f)
  19. }
  20. // ParseConfig parses the user directories config file contained in
  21. // the provided reader.
  22. func ParseConfig(r io.Reader) (*Directories, error) {
  23. dirs := &Directories{}
  24. fieldsMap := map[string]*string{
  25. EnvDesktopDir: &dirs.Desktop,
  26. EnvDownloadDir: &dirs.Download,
  27. EnvDocumentsDir: &dirs.Documents,
  28. EnvMusicDir: &dirs.Music,
  29. EnvPicturesDir: &dirs.Pictures,
  30. EnvVideosDir: &dirs.Videos,
  31. EnvTemplatesDir: &dirs.Templates,
  32. EnvPublicShareDir: &dirs.PublicShare,
  33. }
  34. scanner := bufio.NewScanner(r)
  35. for scanner.Scan() {
  36. line := strings.TrimSpace(scanner.Text())
  37. if len(line) == 0 || line[0] == '#' {
  38. continue
  39. }
  40. if !strings.HasPrefix(line, "XDG_") {
  41. continue
  42. }
  43. parts := strings.Split(line, "=")
  44. if len(parts) < 2 {
  45. continue
  46. }
  47. // Parse key.
  48. field, ok := fieldsMap[strings.TrimSpace(parts[0])]
  49. if !ok {
  50. continue
  51. }
  52. // Parse value.
  53. runes := []rune(strings.TrimSpace(parts[1]))
  54. lenRunes := len(runes)
  55. if lenRunes <= 2 || runes[0] != '"' {
  56. continue
  57. }
  58. for i := 1; i < lenRunes; i++ {
  59. if runes[i] == '"' {
  60. *field = pathutil.ExpandHome(string(runes[1:i]))
  61. break
  62. }
  63. }
  64. }
  65. if err := scanner.Err(); err != nil {
  66. return nil, err
  67. }
  68. return dirs, nil
  69. }