github.com/sagernet/sing-box@v1.9.0-rc.20/cmd/sing-box/cmd_geosite_lookup.go (about)

     1  package main
     2  
     3  import (
     4  	"os"
     5  	"sort"
     6  
     7  	"github.com/sagernet/sing-box/log"
     8  	E "github.com/sagernet/sing/common/exceptions"
     9  
    10  	"github.com/spf13/cobra"
    11  )
    12  
    13  var commandGeositeLookup = &cobra.Command{
    14  	Use:   "lookup [category] <domain>",
    15  	Short: "Check if a domain is in the geosite",
    16  	Args:  cobra.RangeArgs(1, 2),
    17  	Run: func(cmd *cobra.Command, args []string) {
    18  		var (
    19  			source string
    20  			target string
    21  		)
    22  		switch len(args) {
    23  		case 1:
    24  			target = args[0]
    25  		case 2:
    26  			source = args[0]
    27  			target = args[1]
    28  		}
    29  		err := geositeLookup(source, target)
    30  		if err != nil {
    31  			log.Fatal(err)
    32  		}
    33  	},
    34  }
    35  
    36  func init() {
    37  	commandGeoSite.AddCommand(commandGeositeLookup)
    38  }
    39  
    40  func geositeLookup(source string, target string) error {
    41  	var sourceMatcherList []struct {
    42  		code    string
    43  		matcher *searchGeositeMatcher
    44  	}
    45  	if source != "" {
    46  		sourceSet, err := geositeReader.Read(source)
    47  		if err != nil {
    48  			return err
    49  		}
    50  		sourceMatcher, err := newSearchGeositeMatcher(sourceSet)
    51  		if err != nil {
    52  			return E.Cause(err, "compile code: "+source)
    53  		}
    54  		sourceMatcherList = []struct {
    55  			code    string
    56  			matcher *searchGeositeMatcher
    57  		}{
    58  			{
    59  				code:    source,
    60  				matcher: sourceMatcher,
    61  			},
    62  		}
    63  
    64  	} else {
    65  		for _, code := range geositeCodeList {
    66  			sourceSet, err := geositeReader.Read(code)
    67  			if err != nil {
    68  				return err
    69  			}
    70  			sourceMatcher, err := newSearchGeositeMatcher(sourceSet)
    71  			if err != nil {
    72  				return E.Cause(err, "compile code: "+code)
    73  			}
    74  			sourceMatcherList = append(sourceMatcherList, struct {
    75  				code    string
    76  				matcher *searchGeositeMatcher
    77  			}{
    78  				code:    code,
    79  				matcher: sourceMatcher,
    80  			})
    81  		}
    82  	}
    83  	sort.SliceStable(sourceMatcherList, func(i, j int) bool {
    84  		return sourceMatcherList[i].code < sourceMatcherList[j].code
    85  	})
    86  
    87  	for _, matcherItem := range sourceMatcherList {
    88  		if matchRule := matcherItem.matcher.Match(target); matchRule != "" {
    89  			os.Stdout.WriteString("Match code (")
    90  			os.Stdout.WriteString(matcherItem.code)
    91  			os.Stdout.WriteString(") ")
    92  			os.Stdout.WriteString(matchRule)
    93  			os.Stdout.WriteString("\n")
    94  		}
    95  	}
    96  	return nil
    97  }