config_json.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package json
  2. //go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg json -path Main,Json
  3. import (
  4. "context"
  5. "io"
  6. "os"
  7. "os/exec"
  8. "v2ray.com/core"
  9. "v2ray.com/core/common"
  10. "v2ray.com/core/common/platform"
  11. "v2ray.com/core/common/signal"
  12. )
  13. type logWriter struct{}
  14. func (*logWriter) Write(b []byte) (int, error) {
  15. n, err := os.Stderr.Write(b)
  16. if err == nil {
  17. os.Stderr.WriteString(platform.LineSeparator())
  18. }
  19. return n, err
  20. }
  21. func jsonToProto(input io.Reader) (*core.Config, error) {
  22. v2ctl := platform.GetToolLocation("v2ctl")
  23. if _, err := os.Stat(v2ctl); err != nil {
  24. return nil, err
  25. }
  26. cmd := exec.Command(v2ctl, "config")
  27. cmd.Stdin = input
  28. cmd.Stderr = &logWriter{}
  29. cmd.SysProcAttr = getSysProcAttr()
  30. stdoutReader, err := cmd.StdoutPipe()
  31. if err != nil {
  32. return nil, err
  33. }
  34. defer stdoutReader.Close()
  35. if err := cmd.Start(); err != nil {
  36. return nil, err
  37. }
  38. var config *core.Config
  39. loadTask := signal.ExecuteAsync(func() error {
  40. c, err := core.LoadConfig("protobuf", "", stdoutReader)
  41. if err != nil {
  42. return err
  43. }
  44. config = c
  45. return nil
  46. })
  47. waitTask := signal.ExecuteAsync(func() error {
  48. return cmd.Wait()
  49. })
  50. if err := signal.ErrorOrFinish2(context.Background(), loadTask, waitTask); err != nil {
  51. return nil, err
  52. }
  53. return config, nil
  54. }
  55. func init() {
  56. common.Must(core.RegisterConfigLoader(&core.ConfigFormat{
  57. Name: "JSON",
  58. Extension: []string{"json"},
  59. Loader: func(input io.Reader) (*core.Config, error) {
  60. config, err := jsonToProto(input)
  61. if err != nil {
  62. return nil, newError("failed to execute v2ctl to convert config file.").Base(err).AtWarning()
  63. }
  64. return config, nil
  65. },
  66. }))
  67. }