config.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. package main
  2. import (
  3. "encoding/xml"
  4. "io"
  5. "reflect"
  6. "strconv"
  7. "strings"
  8. )
  9. type Configuration struct {
  10. Version int `xml:"version,attr" default:"1"`
  11. Repositories []RepositoryConfiguration `xml:"repository"`
  12. Options OptionsConfiguration `xml:"options"`
  13. XMLName xml.Name `xml:"configuration" json:"-"`
  14. }
  15. type RepositoryConfiguration struct {
  16. Directory string `xml:"directory,attr"`
  17. Nodes []NodeConfiguration `xml:"node"`
  18. }
  19. type NodeConfiguration struct {
  20. NodeID string `xml:"id,attr"`
  21. Addresses []string `xml:"address"`
  22. }
  23. type OptionsConfiguration struct {
  24. ListenAddress string `xml:"listenAddress" default:":22000" ini:"listen-address"`
  25. ReadOnly bool `xml:"readOnly" ini:"read-only"`
  26. AllowDelete bool `xml:"allowDelete" default:"true" ini:"allow-delete"`
  27. FollowSymlinks bool `xml:"followSymlinks" default:"true" ini:"follow-symlinks"`
  28. GUIEnabled bool `xml:"guiEnabled" default:"true" ini:"gui-enabled"`
  29. GUIAddress string `xml:"guiAddress" default:"127.0.0.1:8080" ini:"gui-address"`
  30. GlobalAnnServer string `xml:"globalAnnounceServer" default:"syncthing.nym.se:22025" ini:"global-announce-server"`
  31. GlobalAnnEnabled bool `xml:"globalAnnounceEnabled" default:"true" ini:"global-announce-enabled"`
  32. LocalAnnEnabled bool `xml:"localAnnounceEnabled" default:"true" ini:"local-announce-enabled"`
  33. ParallelRequests int `xml:"parallelRequests" default:"16" ini:"parallel-requests"`
  34. MaxSendKbps int `xml:"maxSendKbps" ini:"max-send-kbps"`
  35. RescanIntervalS int `xml:"rescanIntervalS" default:"60" ini:"rescan-interval"`
  36. ReconnectIntervalS int `xml:"reconnectionIntervalS" default:"60" ini:"reconnection-interval"`
  37. MaxChangeKbps int `xml:"maxChangeKbps" default:"1000" ini:"max-change-bw"`
  38. }
  39. func setDefaults(data interface{}) error {
  40. s := reflect.ValueOf(data).Elem()
  41. t := s.Type()
  42. for i := 0; i < s.NumField(); i++ {
  43. f := s.Field(i)
  44. tag := t.Field(i).Tag
  45. v := tag.Get("default")
  46. if len(v) > 0 {
  47. switch f.Interface().(type) {
  48. case string:
  49. f.SetString(v)
  50. case int:
  51. i, err := strconv.ParseInt(v, 10, 64)
  52. if err != nil {
  53. return err
  54. }
  55. f.SetInt(i)
  56. case bool:
  57. f.SetBool(v == "true")
  58. default:
  59. panic(f.Type())
  60. }
  61. }
  62. }
  63. return nil
  64. }
  65. func readConfigINI(m map[string]string, data interface{}) error {
  66. s := reflect.ValueOf(data).Elem()
  67. t := s.Type()
  68. for i := 0; i < s.NumField(); i++ {
  69. f := s.Field(i)
  70. tag := t.Field(i).Tag
  71. name := tag.Get("ini")
  72. if len(name) == 0 {
  73. name = strings.ToLower(t.Field(i).Name)
  74. }
  75. if v, ok := m[name]; ok {
  76. switch f.Interface().(type) {
  77. case string:
  78. f.SetString(v)
  79. case int:
  80. i, err := strconv.ParseInt(v, 10, 64)
  81. if err == nil {
  82. f.SetInt(i)
  83. }
  84. case bool:
  85. f.SetBool(v == "true")
  86. default:
  87. panic(f.Type())
  88. }
  89. }
  90. }
  91. return nil
  92. }
  93. func writeConfigXML(wr io.Writer, cfg Configuration) error {
  94. e := xml.NewEncoder(wr)
  95. e.Indent("", " ")
  96. err := e.Encode(cfg)
  97. if err != nil {
  98. return err
  99. }
  100. _, err = wr.Write([]byte("\n"))
  101. return err
  102. }
  103. func readConfigXML(rd io.Reader) (Configuration, error) {
  104. var cfg Configuration
  105. setDefaults(&cfg)
  106. setDefaults(&cfg.Options)
  107. var err error
  108. if rd != nil {
  109. err = xml.NewDecoder(rd).Decode(&cfg)
  110. }
  111. return cfg, err
  112. }