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 {
 | 
					port 7011 {
 | 
				
			||||||
    ssl = true
 | 
					    ssl = true
 | 
				
			||||||
    class = "server"
 | 
					    class = "server"
 | 
				
			||||||
 | 
					    bind_ip = "87.237.63.85"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
oper fluffle {
 | 
					oper fluffle {
 | 
				
			||||||
    pass = "foobar"
 | 
					    password = "foobar"
 | 
				
			||||||
    hostmask = "*camelid@*"
 | 
					    hostmask = "*camelid@*"
 | 
				
			||||||
    link = true
 | 
					    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{
 | 
					var configKeywords = configMap{
 | 
				
			||||||
	"port": (*Config).parsePort,
 | 
						"port": (*Config).parsePort,
 | 
				
			||||||
//	"oper": (*Config).parseOper,
 | 
						"oper": (*Config).parseOper,
 | 
				
			||||||
//	"link": (*Config).parseLink,
 | 
					//	"link": (*Config).parseLink,
 | 
				
			||||||
//	"ban":  (*Config).parseBan,
 | 
					//	"ban":  (*Config).parseBan,
 | 
				
			||||||
//	"info": (*Config).parseInfo,
 | 
					//	"info": (*Config).parseInfo,
 | 
				
			||||||
| 
						 | 
					@ -142,6 +142,15 @@ func (conf *Config) expectInt() (int, bool) {
 | 
				
			||||||
	return num, true
 | 
						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 {
 | 
					func (conf *Config) expect(str string) bool {
 | 
				
			||||||
	_, text := conf.next()
 | 
						_, text := conf.next()
 | 
				
			||||||
	if text != str {
 | 
						if text != str {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,16 +1,106 @@
 | 
				
			||||||
package config
 | 
					package config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
						"scanner"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type cOper struct {
 | 
					type cOper struct {
 | 
				
			||||||
	Username, Password string
 | 
						Username, Password string
 | 
				
			||||||
	HostMask []string
 | 
						HostMask []string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Permissions for oper
 | 
						// Permissions for oper
 | 
				
			||||||
	CanKill, CanBan, CanNick, CanLink  bool
 | 
						CanKill, CanBan, CanRenick, CanLink  bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var cOperDefaults = &cOper{
 | 
					var operKeywords = keywordMap{
 | 
				
			||||||
	HostMask: []string{"*@*"},
 | 
						"password": (*Config).parseOperPassword,
 | 
				
			||||||
	CanKill: true, CanBan: true,
 | 
						"hostmask": (*Config).parseOperHostMask,
 | 
				
			||||||
	CanNick: false, CanLink: false,
 | 
						"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
 | 
					package config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"scanner"
 | 
						"scanner"
 | 
				
			||||||
| 
						 | 
					@ -8,40 +9,34 @@ import (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type cPort struct {
 | 
					type cPort struct {
 | 
				
			||||||
	Port     int
 | 
						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)?
 | 
						// Is port a tls.Listener? Does it support compression (no)?
 | 
				
			||||||
	SSL, Zip bool
 | 
						SSL, Zip bool
 | 
				
			||||||
 | 
					 | 
				
			||||||
	// address == "<BindIP>:<Port>"
 | 
					 | 
				
			||||||
	address	 string
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var portKeywords = keywordMap{
 | 
					var portKeywords = keywordMap{
 | 
				
			||||||
//	"bind_ip": (*Config).parsePortBindIP,
 | 
						"bind_ip": (*Config).parsePortBindIP,
 | 
				
			||||||
//	"family": (*Config).parsePortFamily,
 | 
					 | 
				
			||||||
	"class": (*Config).parsePortClass,
 | 
						"class": (*Config).parsePortClass,
 | 
				
			||||||
	"ssl": (*Config).parsePortSSL,
 | 
						"ssl": (*Config).parsePortSSL,
 | 
				
			||||||
//	"zip": (*Config).parsePortZip,
 | 
						"zip": (*Config).parsePortZip,
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var cPortDefaults = cPort{
 | 
					 | 
				
			||||||
	BindIP: "", Family: "tcp", Class: "client",
 | 
					 | 
				
			||||||
	SSL: false, Zip: false,
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func defaultPort() *cPort {
 | 
					func defaultPort() *cPort {
 | 
				
			||||||
	p := cPortDefaults
 | 
						return &cPort{
 | 
				
			||||||
	return &p
 | 
							BindIP: nil, Class: "client",
 | 
				
			||||||
 | 
							SSL: false, Zip: false,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p *cPort) String() string {
 | 
					func (p *cPort) String() string {
 | 
				
			||||||
    str := []string{fmt.Sprintf("port %d {", p.Port)}
 | 
					    str := []string{fmt.Sprintf("port %d {", p.Port)}
 | 
				
			||||||
	if p.BindIP != "" {
 | 
						if p.BindIP != nil {
 | 
				
			||||||
		str = append(str, "\tbind_ip = " + p.BindIP)
 | 
							str = append(str,
 | 
				
			||||||
 | 
								fmt.Sprintf("\tbind_ip = \"%s\"", p.BindIP.String()))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	str = append(str,
 | 
						str = append(str,
 | 
				
			||||||
		fmt.Sprintf("\tfamily = \"%s\"",p.Family),
 | 
					 | 
				
			||||||
		fmt.Sprintf("\tclass  = \"%s\"", p.Class),
 | 
							fmt.Sprintf("\tclass  = \"%s\"", p.Class),
 | 
				
			||||||
		fmt.Sprintf("\tssl    = %t", p.SSL),
 | 
							fmt.Sprintf("\tssl    = %t", p.SSL),
 | 
				
			||||||
		fmt.Sprintf("\tzip    = %t", p.Zip),
 | 
							fmt.Sprintf("\tzip    = %t", p.Zip),
 | 
				
			||||||
| 
						 | 
					@ -66,6 +61,16 @@ func (conf *Config) parsePort() {
 | 
				
			||||||
	fmt.Println(port.String())
 | 
						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{}) {
 | 
					func (conf *Config) parsePortClass(pi interface{}) {
 | 
				
			||||||
	port := pi.(*cPort)
 | 
						port := pi.(*cPort)
 | 
				
			||||||
	tok, text := conf.next()
 | 
						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