func main() { var filepath string var isVersion bool flag.StringVar(&filepath, "f", "/etc/keepalived/keepalived.conf", "keepalived.conf file path") flag.BoolVar(&isVersion, "v", false, "print the version") flag.BoolVar(&log.IsVerbose, "V", false, "verbose log mode") flag.Parse() if isVersion { log.Infof("gokc version %s", Version) os.Exit(0) } if filepath == "" { log.Error("filepath required") } file, err := os.Open(filepath) if err != nil { log.Error(err) } defer file.Close() if err := parser.Parse(file, filepath); err != nil { if e, ok := err.(*parser.Error); ok { msg := colorstring.Color(fmt.Sprintf("[white]%s:%d:%d: [red]%s[reset]", e.Filename, e.Line, e.Column, e.Message)) log.Error(msg) } else { log.Error(err) } } log.Infof("gokc: the configuration file %s syntax is ok", filepath) }
func (l *Lexer) scanInclude(rawfilename string) error { curDir, err := filepath.Abs(".") if err != nil { return err } baseDir := filepath.Dir(l.ctx.filename) os.Chdir(baseDir) defer os.Chdir(curDir) rawpaths, err := filepath.Glob(rawfilename) if err != nil { return err } if len(rawpaths) < 1 { log.Infof("warning: %s: No such file or directory", rawfilename) } prevctx := l.ctx defer func() { l.ctx = prevctx }() for _, rawpath := range rawpaths { relpath := filepath.Join(baseDir, rawpath) log.Verbosef("--> Parsing ... %s\n", relpath) f, err := os.Open(rawpath) if err != nil { return err } l.ctx = NewContext(f, relpath) l.run() f.Close() } return nil }
func (l *Lexer) run() { for { token, s := l.ctx.scanNextToken() if s == "include" { token, s = l.ctx.scanNextToken() if err := l.scanInclude(s); err != nil { l.Error(err.Error()) } token, s = l.ctx.scanNextToken() } if token == scanner.EOF { break } if token == scanner.Ident || token == scanner.String { token = STRING } if _, err := strconv.Atoi(s); err == nil { token = NUMBER } if ip := net.ParseIP(s); ip != nil { if ip.To4() != nil { token = IPV4 } else if ip.To16() != nil { token = IPV6 } else { log.Infof("warning: %s may be IP address?", s) } } if _, _, err := net.ParseCIDR(s); err == nil { token = IP_CIDR } // IPADDR_RANGE(XXX.YYY.ZZZ.WWW-VVV) if ss := strings.Split(s, "-"); len(ss) == 2 { if net.ParseIP(ss[0]) != nil { if ok, _ := regexp.MatchString(`^[\d]{1,3}$`, ss[1]); ok { token = IPADDR_RANGE } } } if ok, _ := regexp.MatchString(`^[[:xdigit:]]{32}$`, s); ok { token = HEX32 } if ok, _ := regexp.MatchString(`/^([[:alnum:]./-_])*`, s); ok { token = PATHSTR } if _, err := mail.ParseAddress(s); err == nil { token = EMAIL } if _, ok := SYMBOL_TABLES[s]; ok { token = SYMBOL_TABLES[s] } l.emitter <- token } }