mirror of https://github.com/fluffle/goirc
164 lines
3.6 KiB
Go
164 lines
3.6 KiB
Go
package main
|
|
|
|
import (
|
|
irc "github.com/fluffle/goirc/client"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
"net"
|
|
"bufio"
|
|
"crypto/tls"
|
|
"crypto/rand"
|
|
"goconfig"
|
|
)
|
|
|
|
const confFile = "rbot.conf"
|
|
var trigger string
|
|
var sections []string
|
|
var conf *config.Config
|
|
|
|
func main() {
|
|
readConf()
|
|
trigger = readConfString("DEFAULT", "trigger")
|
|
readAuth()
|
|
|
|
identdport, _ := conf.String("DEFAULT", "identdport")
|
|
if identdport != "" && identdport != "0" {
|
|
go identd(identdport)
|
|
}
|
|
|
|
sections = conf.Sections()
|
|
for _, s := range sections {
|
|
if strings.Index(s, " ") == -1 && s != "DEFAULT" {
|
|
// found a network
|
|
go connect(s)
|
|
}
|
|
}
|
|
|
|
select { }
|
|
}
|
|
|
|
func connect(network string) {
|
|
if !readConfBool(network, "autoconnect") {
|
|
return
|
|
}
|
|
server := readConfString(network, "server")
|
|
nick := readConfString(network, "nick")
|
|
user := readConfString(network, "user")
|
|
nickserv, _ := conf.String(network, "nickserv")
|
|
|
|
c := irc.New(nick, user, user)
|
|
c.Network = network
|
|
c.SSL = readConfBool(network, "ssl")
|
|
if c.SSL {
|
|
// we don't care about certificate validity
|
|
c.SSLConfig = &tls.Config{Rand: rand.Reader, Time: time.Nanoseconds}
|
|
}
|
|
|
|
c.AddHandler("connected",
|
|
func(conn *irc.Conn, line *irc.Line) {
|
|
fmt.Printf("Connected to %s!\n", conn.Host)
|
|
|
|
if len(nickserv) > 0 {
|
|
conn.Privmsg("NickServ", "IDENTIFY " + nickserv)
|
|
} else {
|
|
autojoin(conn)
|
|
}
|
|
})
|
|
c.AddHandler("privmsg", handlePrivmsg)
|
|
c.AddHandler("mode", handleMode)
|
|
c.AddHandler("join", handleJoin)
|
|
c.AddHandler("invite", handleInvite)
|
|
|
|
var lastAttempt int64 = 0
|
|
for {
|
|
lastAttempt = time.Seconds()
|
|
fmt.Printf("Connecting to %s...\n", server)
|
|
if err := c.Connect(server); err != nil {
|
|
fmt.Printf("Connection error: %s\n", err)
|
|
if time.Seconds() - lastAttempt < 30 {
|
|
time.Sleep(60000000000) // 1 minute
|
|
}
|
|
}
|
|
for err := range c.Err {
|
|
fmt.Printf("goirc error: %s\n", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func autojoin(conn *irc.Conn) {
|
|
for _, s := range sections {
|
|
split := strings.Split(s, " ", 2)
|
|
if len(split) == 2 && split[0] == conn.Network {
|
|
// found a channel
|
|
if readConfBool(s, "autojoin") {
|
|
fmt.Printf("Joining %s on %s\n", split[1], conn.Network)
|
|
conn.Join(split[1])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func readConf() {
|
|
var err os.Error
|
|
conf, err = config.ReadDefault("rbot.conf")
|
|
if (err != nil) {
|
|
fmt.Printf("Config error: %s\n", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
func readConfString(section, option string) string {
|
|
value, err := conf.String(section, option)
|
|
if err != nil {
|
|
panic(fmt.Sprintf("Config error: %s", err))
|
|
}
|
|
return value
|
|
}
|
|
func readConfBool(section, option string) bool {
|
|
value, err := conf.Bool(section, option)
|
|
if err != nil {
|
|
panic(fmt.Sprintf("Config error: %s", err))
|
|
}
|
|
return value
|
|
}
|
|
func updateConf(section, option, value string) {
|
|
conf.AddOption(section, option, value)
|
|
if err := conf.WriteFile(confFile, 0644, ""); err != nil {
|
|
panic("Error while writing to " + confFile)
|
|
}
|
|
// config.WriteFile destroys the config, so
|
|
readConf()
|
|
}
|
|
|
|
func identd(port string) {
|
|
identd, err := net.Listen("tcp", "0.0.0.0:" + port)
|
|
if err != nil {
|
|
fmt.Println("Failed to start identd on port", port)
|
|
return
|
|
}
|
|
defer identd.Close()
|
|
fmt.Println("Started identd on port", port)
|
|
|
|
for {
|
|
conn, err := identd.Accept()
|
|
if err != nil {
|
|
fmt.Println("Failed to accept identd connection")
|
|
continue
|
|
}
|
|
|
|
io := bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn))
|
|
line, err := io.Reader.ReadString('\n')
|
|
if err != nil || len(line) < 2 {
|
|
conn.Close()
|
|
fmt.Println("Failed to read identd request")
|
|
continue
|
|
}
|
|
line = line[:len(line) - 2]
|
|
line = fmt.Sprintf("%s : ERROR : NO-USER\r\n", line)
|
|
io.Writer.WriteString(line)
|
|
time.Sleep(1000000000) // 1 second
|
|
conn.Close()
|
|
}
|
|
}
|