|  | @@ -3,79 +3,23 @@ package json
 | 
	
		
			
				|  |  |  //go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg json -path Main,Json
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import (
 | 
	
		
			
				|  |  | -	"context"
 | 
	
		
			
				|  |  |  	"io"
 | 
	
		
			
				|  |  | -	"os"
 | 
	
		
			
				|  |  | -	"os/exec"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	"v2ray.com/core"
 | 
	
		
			
				|  |  |  	"v2ray.com/core/common"
 | 
	
		
			
				|  |  | -	"v2ray.com/core/common/platform"
 | 
	
		
			
				|  |  | -	"v2ray.com/core/common/signal"
 | 
	
		
			
				|  |  | +	"v2ray.com/core/common/platform/ctlcmd"
 | 
	
		
			
				|  |  |  )
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -type logWriter struct{}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -func (*logWriter) Write(b []byte) (int, error) {
 | 
	
		
			
				|  |  | -	n, err := os.Stderr.Write(b)
 | 
	
		
			
				|  |  | -	if err == nil {
 | 
	
		
			
				|  |  | -		os.Stderr.WriteString(platform.LineSeparator())
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	return n, err
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -func jsonToProto(input io.Reader) (*core.Config, error) {
 | 
	
		
			
				|  |  | -	v2ctl := platform.GetToolLocation("v2ctl")
 | 
	
		
			
				|  |  | -	if _, err := os.Stat(v2ctl); err != nil {
 | 
	
		
			
				|  |  | -		return nil, err
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	cmd := exec.Command(v2ctl, "config")
 | 
	
		
			
				|  |  | -	cmd.Stdin = input
 | 
	
		
			
				|  |  | -	cmd.Stderr = &logWriter{}
 | 
	
		
			
				|  |  | -	cmd.SysProcAttr = getSysProcAttr()
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	stdoutReader, err := cmd.StdoutPipe()
 | 
	
		
			
				|  |  | -	if err != nil {
 | 
	
		
			
				|  |  | -		return nil, err
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	defer stdoutReader.Close()
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if err := cmd.Start(); err != nil {
 | 
	
		
			
				|  |  | -		return nil, err
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var config *core.Config
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	loadTask := signal.ExecuteAsync(func() error {
 | 
	
		
			
				|  |  | -		c, err := core.LoadConfig("protobuf", "", stdoutReader)
 | 
	
		
			
				|  |  | -		if err != nil {
 | 
	
		
			
				|  |  | -			return err
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		config = c
 | 
	
		
			
				|  |  | -		return nil
 | 
	
		
			
				|  |  | -	})
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	waitTask := signal.ExecuteAsync(func() error {
 | 
	
		
			
				|  |  | -		return cmd.Wait()
 | 
	
		
			
				|  |  | -	})
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if err := signal.ErrorOrFinish2(context.Background(), loadTask, waitTask); err != nil {
 | 
	
		
			
				|  |  | -		return nil, err
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	return config, nil
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  func init() {
 | 
	
		
			
				|  |  |  	common.Must(core.RegisterConfigLoader(&core.ConfigFormat{
 | 
	
		
			
				|  |  |  		Name:      "JSON",
 | 
	
		
			
				|  |  |  		Extension: []string{"json"},
 | 
	
		
			
				|  |  |  		Loader: func(input io.Reader) (*core.Config, error) {
 | 
	
		
			
				|  |  | -			config, err := jsonToProto(input)
 | 
	
		
			
				|  |  | +			jsonContent, err := ctlcmd.Run([]string{"config"}, input)
 | 
	
		
			
				|  |  |  			if err != nil {
 | 
	
		
			
				|  |  |  				return nil, newError("failed to execute v2ctl to convert config file.").Base(err).AtWarning()
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  | -			return config, nil
 | 
	
		
			
				|  |  | +			return core.LoadConfig("protobuf", "", &jsonContent)
 | 
	
		
			
				|  |  |  		},
 | 
	
		
			
				|  |  |  	}))
 | 
	
		
			
				|  |  |  }
 |