mirror of https://github.com/fluffle/goirc
WIP on config parser before attempting to learn FSMs
This commit is contained in:
parent
b3f98e762e
commit
377fbcd3af
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,
|
||||||
|
"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,
|
CanKill: true, CanBan: true,
|
||||||
CanNick: false, CanLink: false,
|
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…
Reference in New Issue