mirror of
				https://github.com/fluffle/goirc
				synced 2025-11-04 03:58:03 +00:00 
			
		
		
		
	WIP on config parser before attempting to learn FSMs
This commit is contained in:
		
							parent
							
								
									b3f98e762e
								
							
						
					
					
						commit
						377fbcd3af
					
				
					 4 changed files with 142 additions and 24 deletions
				
			
		
							
								
								
									
										10
									
								
								server.cfg
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								server.cfg
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -6,11 +6,19 @@ port 6697 { ssl = true }
 | 
			
		|||
port 7011 {
 | 
			
		||||
    ssl = true
 | 
			
		||||
    class = "server"
 | 
			
		||||
    bind_ip = "87.237.63.85"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
oper fluffle {
 | 
			
		||||
    pass = "foobar"
 | 
			
		||||
    password = "foobar"
 | 
			
		||||
    hostmask = "*camelid@*"
 | 
			
		||||
    link = true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
oper "bb101" {
 | 
			
		||||
    password = "dongs"
 | 
			
		||||
    hostmask = "*bb10@*.enta.net"
 | 
			
		||||
    hostmask = "*bb@*.dongs.com"
 | 
			
		||||
    renick = true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,7 +36,7 @@ type keywordMap map[string]func(*Config, interface{})
 | 
			
		|||
 | 
			
		||||
var configKeywords = configMap{
 | 
			
		||||
	"port": (*Config).parsePort,
 | 
			
		||||
//	"oper": (*Config).parseOper,
 | 
			
		||||
	"oper": (*Config).parseOper,
 | 
			
		||||
//	"link": (*Config).parseLink,
 | 
			
		||||
//	"ban":  (*Config).parseBan,
 | 
			
		||||
//	"info": (*Config).parseInfo,
 | 
			
		||||
| 
						 | 
				
			
			@ -142,6 +142,15 @@ func (conf *Config) expectInt() (int, bool) {
 | 
			
		|||
	return num, true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (conf *Config) expectString() (string, bool) {
 | 
			
		||||
	tok, text := conf.next()
 | 
			
		||||
	if tok != scanner.String && tok != scanner.Ident {
 | 
			
		||||
		conf.parseError("Expected string, got '%s'", text)
 | 
			
		||||
		return "", false
 | 
			
		||||
	}
 | 
			
		||||
	return text, true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (conf *Config) expect(str string) bool {
 | 
			
		||||
	_, text := conf.next()
 | 
			
		||||
	if text != str {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,16 +1,106 @@
 | 
			
		|||
package config
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"scanner"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type cOper struct {
 | 
			
		||||
	Username, Password string
 | 
			
		||||
	HostMask []string
 | 
			
		||||
 | 
			
		||||
	// Permissions for oper
 | 
			
		||||
	CanKill, CanBan, CanNick, CanLink  bool
 | 
			
		||||
	CanKill, CanBan, CanRenick, CanLink  bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var cOperDefaults = &cOper{
 | 
			
		||||
	HostMask: []string{"*@*"},
 | 
			
		||||
	CanKill: true, CanBan: true,
 | 
			
		||||
	CanNick: false, CanLink: false,
 | 
			
		||||
var operKeywords = keywordMap{
 | 
			
		||||
	"password": (*Config).parseOperPassword,
 | 
			
		||||
	"hostmask": (*Config).parseOperHostMask,
 | 
			
		||||
	"kill": (*Config).parseOperKill,
 | 
			
		||||
	"ban": (*Config).parseOperBan,
 | 
			
		||||
	"renick": (*Config).parseOperRenick,
 | 
			
		||||
	"link": (*Config).parseOperLink,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func defaultOper() *cOper {
 | 
			
		||||
	return &cOper{
 | 
			
		||||
		HostMask: []string{},
 | 
			
		||||
		CanKill: true, CanBan: true,
 | 
			
		||||
		CanRenick: false, CanLink: false,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o *cOper) String() string {
 | 
			
		||||
    str := []string{fmt.Sprintf("oper \"%s\" {", o.Username)}
 | 
			
		||||
	str = append(str, fmt.Sprintf("\tpassword = \"%s\"", o.Password))
 | 
			
		||||
	if len(o.HostMask) == 0 {
 | 
			
		||||
		str = append(str, fmt.Sprintf("\thostmask = \"*@*\""))
 | 
			
		||||
	} else {
 | 
			
		||||
		for _, h := range o.HostMask {
 | 
			
		||||
			str = append(str, fmt.Sprintf("\thostmask = \"%s\"", h))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	str = append(str,
 | 
			
		||||
		fmt.Sprintf("\tkill    = %t", o.CanKill),
 | 
			
		||||
		fmt.Sprintf("\tban     = %t", o.CanBan),
 | 
			
		||||
		fmt.Sprintf("\trenick  = %t", o.CanRenick),
 | 
			
		||||
		fmt.Sprintf("\tlink    = %t", o.CanLink),
 | 
			
		||||
		"}",
 | 
			
		||||
	)
 | 
			
		||||
	return strings.Join(str, "\n")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (conf *Config) parseOper() {
 | 
			
		||||
	oper := defaultOper()
 | 
			
		||||
	tok, text := conf.next()
 | 
			
		||||
	if tok != scanner.String && tok != scanner.Ident {
 | 
			
		||||
		conf.parseError("Invalid username '%s'", text)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	oper.Username = text
 | 
			
		||||
	conf.parseKwBlock(oper, "oper", operKeywords)
 | 
			
		||||
	fmt.Println(oper.String())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (conf *Config) parseOperPassword(oi interface{}) {
 | 
			
		||||
	oper := oi.(*cOper)
 | 
			
		||||
	if pass, ok := conf.expectString(); ok {
 | 
			
		||||
		oper.Password = pass
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (conf *Config) parseOperHostMask(oi interface{}) {
 | 
			
		||||
	oper := oi.(*cOper)
 | 
			
		||||
	if mask, ok := conf.expectString(); ok {
 | 
			
		||||
		oper.HostMask = append(oper.HostMask, mask)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (conf *Config) parseOperKill(oi interface{}) {
 | 
			
		||||
	oper := oi.(*cOper)
 | 
			
		||||
	if kill, ok := conf.expectBool(); ok {
 | 
			
		||||
		oper.CanKill = kill
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (conf *Config) parseOperBan(oi interface{}) {
 | 
			
		||||
	oper := oi.(*cOper)
 | 
			
		||||
	if ban, ok := conf.expectBool(); ok {
 | 
			
		||||
		oper.CanBan = ban
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (conf *Config) parseOperRenick(oi interface{}) {
 | 
			
		||||
	oper := oi.(*cOper)
 | 
			
		||||
	if renick, ok := conf.expectBool(); ok {
 | 
			
		||||
		oper.CanRenick = renick
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (conf *Config) parseOperLink(oi interface{}) {
 | 
			
		||||
	oper := oi.(*cOper)
 | 
			
		||||
	if link, ok := conf.expectBool(); ok {
 | 
			
		||||
		oper.CanLink = link
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
package config
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"scanner"
 | 
			
		||||
| 
						 | 
				
			
			@ -8,40 +9,34 @@ import (
 | 
			
		|||
 | 
			
		||||
type cPort struct {
 | 
			
		||||
	Port     int
 | 
			
		||||
	BindIP, Family, Class string
 | 
			
		||||
	BindIP   net.IP // bind to a specific IP for listen port
 | 
			
		||||
	Class    string // "server" or "client"
 | 
			
		||||
 | 
			
		||||
	// Is port a tls.Listener? Does it support compression (no)?
 | 
			
		||||
	SSL, Zip bool
 | 
			
		||||
 | 
			
		||||
	// address == "<BindIP>:<Port>"
 | 
			
		||||
	address	 string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var portKeywords = keywordMap{
 | 
			
		||||
//	"bind_ip": (*Config).parsePortBindIP,
 | 
			
		||||
//	"family": (*Config).parsePortFamily,
 | 
			
		||||
	"bind_ip": (*Config).parsePortBindIP,
 | 
			
		||||
	"class": (*Config).parsePortClass,
 | 
			
		||||
	"ssl": (*Config).parsePortSSL,
 | 
			
		||||
//	"zip": (*Config).parsePortZip,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var cPortDefaults = cPort{
 | 
			
		||||
	BindIP: "", Family: "tcp", Class: "client",
 | 
			
		||||
	SSL: false, Zip: false,
 | 
			
		||||
	"zip": (*Config).parsePortZip,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func defaultPort() *cPort {
 | 
			
		||||
	p := cPortDefaults
 | 
			
		||||
	return &p
 | 
			
		||||
	return &cPort{
 | 
			
		||||
		BindIP: nil, Class: "client",
 | 
			
		||||
		SSL: false, Zip: false,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *cPort) String() string {
 | 
			
		||||
    str := []string{fmt.Sprintf("port %d {", p.Port)}
 | 
			
		||||
	if p.BindIP != "" {
 | 
			
		||||
		str = append(str, "\tbind_ip = " + p.BindIP)
 | 
			
		||||
	if p.BindIP != nil {
 | 
			
		||||
		str = append(str,
 | 
			
		||||
			fmt.Sprintf("\tbind_ip = \"%s\"", p.BindIP.String()))
 | 
			
		||||
	}
 | 
			
		||||
	str = append(str,
 | 
			
		||||
		fmt.Sprintf("\tfamily = \"%s\"",p.Family),
 | 
			
		||||
		fmt.Sprintf("\tclass  = \"%s\"", p.Class),
 | 
			
		||||
		fmt.Sprintf("\tssl    = %t", p.SSL),
 | 
			
		||||
		fmt.Sprintf("\tzip    = %t", p.Zip),
 | 
			
		||||
| 
						 | 
				
			
			@ -66,6 +61,16 @@ func (conf *Config) parsePort() {
 | 
			
		|||
	fmt.Println(port.String())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (conf *Config) parsePortBindIP(pi interface{}) {
 | 
			
		||||
	port := pi.(*cPort)
 | 
			
		||||
	_, text := conf.next()
 | 
			
		||||
	if ip := net.ParseIP(text); ip != nil {
 | 
			
		||||
		port.BindIP = ip
 | 
			
		||||
	} else {
 | 
			
		||||
		conf.parseError("'%s' is not a valid IP address", text)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (conf *Config) parsePortClass(pi interface{}) {
 | 
			
		||||
	port := pi.(*cPort)
 | 
			
		||||
	tok, text := conf.next()
 | 
			
		||||
| 
						 | 
				
			
			@ -84,3 +89,9 @@ func (conf *Config) parsePortSSL(pi interface{}) {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (conf *Config) parsePortZip(pi interface{}) {
 | 
			
		||||
	port := pi.(*cPort)
 | 
			
		||||
	if zip, ok := conf.expectBool(); ok {
 | 
			
		||||
		port.Zip = zip
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue