config_json.go 1.5 KB

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