| 
					
				 | 
			
			
				@@ -1,23 +1,35 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 package main 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"context" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"io" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"os" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"os/exec" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"v2ray.com/core" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"v2ray.com/core/common" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"v2ray.com/core/common/platform" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"v2ray.com/core/common/signal" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+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") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	_, err := os.Stat(v2ctl) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if _, err := os.Stat(v2ctl); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return nil, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	cmd := exec.Command(v2ctl, "config") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	cmd.Stdin = input 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	cmd.Stderr = os.Stderr 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	cmd.Stderr = &logWriter{} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	cmd.SysProcAttr = getSysProcAttr() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	stdoutReader, err := cmd.StdoutPipe() 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -30,19 +42,34 @@ func jsonToProto(input io.Reader) (*core.Config, error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return nil, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	config, err := core.LoadConfig(core.ConfigFormat_Protobuf, stdoutReader) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	var config *core.Config 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	loadTask := signal.ExecuteAsync(func() error { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		c, err := core.LoadConfig(core.ConfigFormat_Protobuf, stdoutReader) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		config = c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	waitTask := signal.ExecuteAsync(func() error { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return cmd.Wait() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	cmd.Wait() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if err := signal.ErrorOrFinish2(context.Background(), loadTask, waitTask); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return nil, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	return config, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return config, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func init() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	core.RegisterConfigLoader(core.ConfigFormat_JSON, func(input io.Reader) (*core.Config, error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	common.Must(core.RegisterConfigLoader(core.ConfigFormat_JSON, func(input io.Reader) (*core.Config, error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		config, err := jsonToProto(input) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return nil, newError("failed to execute v2ctl to convert config file.").Base(err).AtWarning() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return config, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	})) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |