From 58f7d6dabf2679ba3f32a1157ee10b66649cdc8f Mon Sep 17 00:00:00 2001 From: Jeremy Latt Date: Tue, 25 Feb 2014 09:35:55 -0800 Subject: [PATCH 01/10] add comments explaining config file --- config.json | 52 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/config.json b/config.json index d33117ab..b607611a 100644 --- a/config.json +++ b/config.json @@ -1,13 +1,39 @@ -{ "name": "irc.example.com", - "motd": "motd.txt", - "listeners": [ - { "address": "localhost:7777" }, - { "address": "[::1]:7777" } ], - "operators": [ - { "name": "root", - "password": "JDJhJDEwJFRWWGUya2E3Unk5bnZlb2o3alJ0ZnVQQm9ZVW1HOE53L29nVHg5QWh5TnpaMmtOaEwya1Vl" } ], - "debug": { - "net": true, - "client": false, - "channel": false, - "server": false } } +// Ergonomadic IRC Server Config +// ----------------------------- +// Passwords are generated by `ergonomadic -genpasswd "$plaintext"`. +// Comments are not allowed in the actual config file. +{ + // `name` is usually a hostname. + "name": "irc.example.com", + + // The path to the MOTD is relative to this file's directory. + "motd": "motd.txt", + + // PASS command password + "password": "JDJhJDA0JHBBenUyV3Z5UU5iWUpiYmlNMlNLZC5VRDZDM21HUzFVbmxLUUI3NTVTLkZJOERLdUFaUWNt", + + // `listeners` are places to bind and listen for + // connections. http://golang.org/pkg/net/#Dial demonstrates valid + // values for `net` and `address`. `net` is optional and defaults + // to `tcp`. + "listeners": [ { + "address": "localhost:7777" + }, { + "net": "tcp6", + "address": "[::1]:7777" + } ], + + // Operators for the OPER command + "operators": [ { + "name": "root", + "password": "JDJhJDA0JHBBenUyV3Z5UU5iWUpiYmlNMlNLZC5VRDZDM21HUzFVbmxLUUI3NTVTLkZJOERLdUFaUWNt" + } ], + + // Global debug flags. `net` generates a lot of output. + "debug": { + "net": true, + "client": false, + "channel": false, + "server": false + } +} From 0531c404818a3e6931412592ec41e67172b2fb57 Mon Sep 17 00:00:00 2001 From: Jeremy Latt Date: Tue, 25 Feb 2014 09:42:50 -0800 Subject: [PATCH 02/10] simplify semantic version constant --- irc/constants.go | 6 +++--- irc/reply.go | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/irc/constants.go b/irc/constants.go index 74b43611..a831c6d2 100644 --- a/irc/constants.go +++ b/irc/constants.go @@ -23,9 +23,9 @@ var ( ) const ( - SERVER_VERSION = "1.1.0" - CRLF = "\r\n" - MAX_REPLY_LEN = 512 - len(CRLF) + SEMVER = "ergonomadic-1.1.0" + CRLF = "\r\n" + MAX_REPLY_LEN = 512 - len(CRLF) LOGIN_TIMEOUT = time.Minute / 2 // how long the client has to login IDLE_TIMEOUT = time.Minute // how long before a client is considered idle diff --git a/irc/reply.go b/irc/reply.go index 50034214..404a3471 100644 --- a/irc/reply.go +++ b/irc/reply.go @@ -151,7 +151,7 @@ func (target *Client) RplWelcome() { func (target *Client) RplYourHost() { target.NumericReply(RPL_YOURHOST, - ":Your host is %s, running version %s", target.server.name, SERVER_VERSION) + ":Your host is %s, running version %s", target.server.name, SEMVER) } func (target *Client) RplCreated() { @@ -161,7 +161,7 @@ func (target *Client) RplCreated() { func (target *Client) RplMyInfo() { target.NumericReply(RPL_MYINFO, - "%s %s aiOorsw abeIikmntpqrsl", target.server.name, SERVER_VERSION) + "%s %s aiOorsw abeIikmntpqrsl", target.server.name, SEMVER) } func (target *Client) RplUModeIs(client *Client) { @@ -371,7 +371,7 @@ func (target *Client) RplWhoisChannels(client *Client) { func (target *Client) RplVersion() { target.NumericReply(RPL_VERSION, - "ergonomadic-%s %s", SERVER_VERSION, target.server.name) + "%s %s", SEMVER, target.server.name) } func (target *Client) RplInviting(invitee *Client, channel string) { From 5930445313c8cc690b99d931b6f3f640d10cf4ed Mon Sep 17 00:00:00 2001 From: Jeremy Latt Date: Tue, 25 Feb 2014 09:54:14 -0800 Subject: [PATCH 03/10] MIT license --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..958be4ae --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Jeremy Latt + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From de5538f5d5d7a4fcfdf3f3ddfbd7e7e0a26201f5 Mon Sep 17 00:00:00 2001 From: Jeremy Latt Date: Tue, 25 Feb 2014 10:04:59 -0800 Subject: [PATCH 04/10] add persistent flag for channels --- irc/channel.go | 4 ++-- irc/constants.go | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/irc/channel.go b/irc/channel.go index a95ebeba..7254eea2 100644 --- a/irc/channel.go +++ b/irc/channel.go @@ -166,7 +166,7 @@ func (channel *Channel) Part(client *Client, message string) { } channel.Quit(client) - if channel.IsEmpty() { + if !channel.flags[Persistent] && channel.IsEmpty() { channel.server.channels.Remove(channel) } } @@ -296,7 +296,7 @@ func (channel *Channel) applyMode(client *Client, change *ChannelModeChange) boo } client.RplEndOfMaskList(change.mode, channel) - case Moderated, NoOutside, OpOnlyTopic, Private: + case Moderated, NoOutside, OpOnlyTopic, Persistent, Private: return channel.applyModeFlag(client, change.mode, change.op) case Key: diff --git a/irc/constants.go b/irc/constants.go index a831c6d2..fbec13e2 100644 --- a/irc/constants.go +++ b/irc/constants.go @@ -223,6 +223,7 @@ const ( Moderated ChannelMode = 'm' // flag NoOutside ChannelMode = 'n' // flag OpOnlyTopic ChannelMode = 't' // flag + Persistent ChannelMode = 'P' // flag Private ChannelMode = 'p' // flag Quiet ChannelMode = 'q' // flag ReOp ChannelMode = 'r' // flag From 02abeeb164130e3aad760547f4def696794a11dd Mon Sep 17 00:00:00 2001 From: Jeremy Latt Date: Tue, 25 Feb 2014 11:11:34 -0800 Subject: [PATCH 05/10] persistent channels persisted to a sqlite db --- README.md | 1 + ergonomadic.go | 30 ++++++++++++++++++++++++++++++ irc/channel.go | 20 +++++++++++++++++++- irc/config.go | 10 +++++++--- irc/server.go | 46 +++++++++++++++++++++++++++++++++++++++++++++- irc/types.go | 10 ++++++++++ 6 files changed, 112 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index cc68f07b..5702e183 100644 --- a/README.md +++ b/README.md @@ -40,5 +40,6 @@ byte strings. You can generate them with e.g. `ergonomadic -genpasswd ```sh go get go install +ergonomadic -conf '/path/to/config.json' -initdb ergonomadic -conf '/path/to/config.json' ``` diff --git a/ergonomadic.go b/ergonomadic.go index 9321e5da..e4633b6e 100644 --- a/ergonomadic.go +++ b/ergonomadic.go @@ -2,11 +2,14 @@ package main import ( "code.google.com/p/go.crypto/bcrypt" + "database/sql" "encoding/base64" "flag" "fmt" "github.com/jlatt/ergonomadic/irc" + _ "github.com/mattn/go-sqlite3" "log" + "os" ) func genPasswd(passwd string) { @@ -18,8 +21,30 @@ func genPasswd(passwd string) { fmt.Println(encoded) } +func initDB(config *irc.Config) { + os.Remove(config.Database()) + + db, err := sql.Open("sqlite3", config.Database()) + if err != nil { + log.Fatal(err) + } + defer db.Close() + + _, err = db.Exec(` + CREATE TABLE channel ( + name TEXT NOT NULL UNIQUE, + flags TEXT, + key TEXT, + topic TEXT, + user_limit INTEGER)`) + if err != nil { + log.Fatal(err) + } +} + func main() { conf := flag.String("conf", "ergonomadic.json", "ergonomadic config file") + initdb := flag.Bool("initdb", false, "initialize database") passwd := flag.String("genpasswd", "", "bcrypt a password") flag.Parse() @@ -31,9 +56,14 @@ func main() { config, err := irc.LoadConfig(*conf) if err != nil { log.Fatal(err) + } + + if *initdb { + initDB(config) return } + // TODO move to data structures irc.DEBUG_NET = config.Debug["net"] irc.DEBUG_CLIENT = config.Debug["client"] irc.DEBUG_CHANNEL = config.Debug["channel"] diff --git a/irc/channel.go b/irc/channel.go index 7254eea2..fb66073b 100644 --- a/irc/channel.go +++ b/irc/channel.go @@ -33,7 +33,14 @@ func NewChannel(s *Server, name string) *Channel { name: name, server: s, } + s.channels[name] = channel + s.db.Exec(`INSERT INTO channel + (name, flags, key, topic, user_limit) + VALUES (?, ?, ?, ?, ?)`, + channel.name, channel.flags.String(), channel.key, channel.topic, + channel.userLimit) + return channel } @@ -142,7 +149,9 @@ func (channel *Channel) Join(client *Client, key string) { client.channels.Add(channel) channel.members.Add(client) if len(channel.members) == 1 { - channel.members[client][ChannelCreator] = true + if !channel.flags[Persistent] { + channel.members[client][ChannelCreator] = true + } channel.members[client][ChannelOperator] = true } @@ -198,6 +207,10 @@ func (channel *Channel) SetTopic(client *Client, topic string) { } channel.topic = topic + channel.server.db.Exec(` + UPDATE channel + SET topic = ? + WHERE name = ?`, channel.topic, channel.name) reply := RplTopicMsg(client, channel) for member := range channel.members { @@ -361,6 +374,11 @@ func (channel *Channel) Mode(client *Client, changes ChannelModeChanges) { for member := range channel.members { member.Reply(reply) } + + channel.server.db.Exec(` + UPDATE channel + SET flags = ? + WHERE name = ?`, channel.flags.String(), channel.name) } } diff --git a/irc/config.go b/irc/config.go index 5ddebb21..07518f00 100644 --- a/irc/config.go +++ b/irc/config.go @@ -26,6 +26,11 @@ type Config struct { Name string Operators []OperatorConfig Password string + directory string +} + +func (conf *Config) Database() string { + return filepath.Join(conf.directory, "ergonomadic.db") } func (conf *Config) PasswordBytes() []byte { @@ -75,9 +80,8 @@ func LoadConfig(filename string) (config *Config, err error) { return } - dir := filepath.Dir(filename) - config.MOTD = filepath.Join(dir, config.MOTD) - + config.directory = filepath.Dir(filename) + config.MOTD = filepath.Join(config.directory, config.MOTD) for _, lconf := range config.Listeners { if lconf.Net == "" { lconf.Net = "tcp" diff --git a/irc/server.go b/irc/server.go index 889bea8f..00a8ff94 100644 --- a/irc/server.go +++ b/irc/server.go @@ -4,11 +4,14 @@ import ( "bufio" "crypto/rand" "crypto/tls" + "database/sql" "encoding/binary" "fmt" + _ "github.com/mattn/go-sqlite3" "log" "net" "os" + "os/signal" "runtime" "runtime/debug" "runtime/pprof" @@ -21,30 +24,65 @@ type Server struct { clients ClientNameMap commands chan Command ctime time.Time + db *sql.DB idle chan *Client motdFile string name string newConns chan net.Conn operators map[string][]byte password []byte + signals chan os.Signal timeout chan *Client } func NewServer(config *Config) *Server { + db, err := sql.Open("sqlite3", config.Database()) + if err != nil { + log.Fatal(err) + } + server := &Server{ channels: make(ChannelNameMap), clients: make(ClientNameMap), commands: make(chan Command, 16), ctime: time.Now(), + db: db, idle: make(chan *Client, 16), motdFile: config.MOTD, name: config.Name, newConns: make(chan net.Conn, 16), operators: config.OperatorsMap(), password: config.PasswordBytes(), + signals: make(chan os.Signal, 1), timeout: make(chan *Client, 16), } + signal.Notify(server.signals, os.Interrupt, os.Kill) + + rows, err := db.Query(` + SELECT name, flags, key, topic, user_limit + FROM channel`) + if err != nil { + log.Fatal(err) + } + for rows.Next() { + var name, flags, key, topic string + var userLimit uint64 + err = rows.Scan(&name, &flags, &key, &topic, &userLimit) + if err != nil { + log.Println(err) + continue + } + + channel := NewChannel(server, name) + for flag := range flags { + channel.flags[ChannelMode(flag)] = true + } + channel.key = key + channel.topic = topic + channel.userLimit = userLimit + } + for _, listenerConf := range config.Listeners { go server.listen(listenerConf) } @@ -97,8 +135,14 @@ func (server *Server) processCommand(cmd Command) { } func (server *Server) Run() { - for { + done := false + for !done { select { + case <-server.signals: + server.db.Close() + done = true + continue + case conn := <-server.newConns: NewClient(server, conn) diff --git a/irc/types.go b/irc/types.go index 0f15d314..8e25f2f6 100644 --- a/irc/types.go +++ b/irc/types.go @@ -106,6 +106,16 @@ func (clients ClientNameMap) Remove(client *Client) error { type ChannelModeSet map[ChannelMode]bool +func (set ChannelModeSet) String() string { + strs := make([]string, len(set)) + index := 0 + for mode := range set { + strs[index] = mode.String() + index += 1 + } + return strings.Join(strs, "") +} + type ClientSet map[*Client]bool func (clients ClientSet) Add(client *Client) { From e409bcec99531a517cc3374f8be4a5cddaa061c8 Mon Sep 17 00:00:00 2001 From: Jeremy Latt Date: Tue, 25 Feb 2014 13:12:11 -0800 Subject: [PATCH 06/10] simplify new channel insert --- irc/channel.go | 6 +----- irc/constants.go | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/irc/channel.go b/irc/channel.go index fb66073b..69e39077 100644 --- a/irc/channel.go +++ b/irc/channel.go @@ -35,11 +35,7 @@ func NewChannel(s *Server, name string) *Channel { } s.channels[name] = channel - s.db.Exec(`INSERT INTO channel - (name, flags, key, topic, user_limit) - VALUES (?, ?, ?, ?, ?)`, - channel.name, channel.flags.String(), channel.key, channel.topic, - channel.userLimit) + s.db.Exec(`INSERT INTO channel (name) VALUES (?)`, channel.name) return channel } diff --git a/irc/constants.go b/irc/constants.go index fbec13e2..35ff058c 100644 --- a/irc/constants.go +++ b/irc/constants.go @@ -209,7 +209,7 @@ const ( LocalOperator UserMode = 'O' Operator UserMode = 'o' Restricted UserMode = 'r' - ServerNotice UserMode = 's' + ServerNotice UserMode = 's' // deprecated WallOps UserMode = 'w' Anonymous ChannelMode = 'a' // flag From a30bb540e9df8dc5bc11a1f367df18c331766259 Mon Sep 17 00:00:00 2001 From: Jeremy Latt Date: Tue, 25 Feb 2014 13:19:59 -0800 Subject: [PATCH 07/10] rewrite parseLine to be much saner about utf8 --- irc/commands.go | 34 ++++++++-------------------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/irc/commands.go b/irc/commands.go index 2b45a128..feb106c4 100644 --- a/irc/commands.go +++ b/irc/commands.go @@ -96,35 +96,17 @@ var ( spacesExpr = regexp.MustCompile(` +`) ) -func parseArg(line string) (arg string, rest string) { - if line == "" { - return - } - - if strings.HasPrefix(line, ":") { - arg = line[1:] +func parseLine(line string) (StringCode, []string) { + var parts []string + if colonIndex := strings.IndexRune(line, ':'); colonIndex >= 0 { + lastArg := line[colonIndex+len(":"):] + line = line[:colonIndex-len(" ")] + parts = append(spacesExpr.Split(line, -1), lastArg) } else { - parts := spacesExpr.Split(line, 2) - arg = parts[0] - if len(parts) > 1 { - rest = parts[1] - } - } - return -} + parts = spacesExpr.Split(line, -1) -func parseLine(line string) (command StringCode, args []string) { - args = make([]string, 0) - for arg, rest := parseArg(line); arg != ""; arg, rest = parseArg(rest) { - if arg == "" { - continue - } - args = append(args, arg) } - if len(args) > 0 { - command, args = StringCode(strings.ToUpper(args[0])), args[1:] - } - return + return StringCode(strings.ToUpper(parts[0])), parts[1:] } // [args...] From b30e247e7741cc2b46af2bc0dbd281a37031e9ed Mon Sep 17 00:00:00 2001 From: Jeremy Latt Date: Tue, 25 Feb 2014 15:57:35 -0800 Subject: [PATCH 08/10] properly persist channels --- ergonomadic.go | 8 ++++---- irc/channel.go | 22 ++++++++++++++-------- irc/server.go | 20 ++++++++++++-------- irc/types.go | 3 +++ 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/ergonomadic.go b/ergonomadic.go index e4633b6e..e04f9e8a 100644 --- a/ergonomadic.go +++ b/ergonomadic.go @@ -33,10 +33,10 @@ func initDB(config *irc.Config) { _, err = db.Exec(` CREATE TABLE channel ( name TEXT NOT NULL UNIQUE, - flags TEXT, - key TEXT, - topic TEXT, - user_limit INTEGER)`) + flags TEXT NOT NULL, + key TEXT NOT NULL, + topic TEXT NOT NULL, + user_limit INTEGER DEFAULT 0)`) if err != nil { log.Fatal(err) } diff --git a/irc/channel.go b/irc/channel.go index 69e39077..26f8909e 100644 --- a/irc/channel.go +++ b/irc/channel.go @@ -35,7 +35,6 @@ func NewChannel(s *Server, name string) *Channel { } s.channels[name] = channel - s.db.Exec(`INSERT INTO channel (name) VALUES (?)`, channel.name) return channel } @@ -203,15 +202,13 @@ func (channel *Channel) SetTopic(client *Client, topic string) { } channel.topic = topic - channel.server.db.Exec(` - UPDATE channel - SET topic = ? - WHERE name = ?`, channel.topic, channel.name) reply := RplTopicMsg(client, channel) for member := range channel.members { member.Reply(reply) } + + channel.Persist() } func (channel *Channel) CanSpeak(client *Client) bool { @@ -371,10 +368,19 @@ func (channel *Channel) Mode(client *Client, changes ChannelModeChanges) { member.Reply(reply) } + channel.Persist() + } +} + +func (channel *Channel) Persist() { + if channel.flags[Persistent] { channel.server.db.Exec(` - UPDATE channel - SET flags = ? - WHERE name = ?`, channel.flags.String(), channel.name) + INSERT OR REPLACE INTO channel + (name, flags, key, topic) + VALUES (?, ?, ?, ?)`, + channel.name, channel.flags.String(), channel.key, channel.topic) + } else { + channel.server.db.Exec(`DELETE FROM channel WHERE name = ?`, channel.name) } } diff --git a/irc/server.go b/irc/server.go index 00a8ff94..7ac9367d 100644 --- a/irc/server.go +++ b/irc/server.go @@ -59,7 +59,17 @@ func NewServer(config *Config) *Server { signal.Notify(server.signals, os.Interrupt, os.Kill) - rows, err := db.Query(` + server.loadChannels() + + for _, listenerConf := range config.Listeners { + go server.listen(listenerConf) + } + + return server +} + +func (server *Server) loadChannels() { + rows, err := server.db.Query(` SELECT name, flags, key, topic, user_limit FROM channel`) if err != nil { @@ -75,19 +85,13 @@ func NewServer(config *Config) *Server { } channel := NewChannel(server, name) - for flag := range flags { + for _, flag := range flags { channel.flags[ChannelMode(flag)] = true } channel.key = key channel.topic = topic channel.userLimit = userLimit } - - for _, listenerConf := range config.Listeners { - go server.listen(listenerConf) - } - - return server } func (server *Server) processCommand(cmd Command) { diff --git a/irc/types.go b/irc/types.go index 8e25f2f6..d8d9f9f8 100644 --- a/irc/types.go +++ b/irc/types.go @@ -107,6 +107,9 @@ func (clients ClientNameMap) Remove(client *Client) error { type ChannelModeSet map[ChannelMode]bool func (set ChannelModeSet) String() string { + if len(set) == 0 { + return "" + } strs := make([]string, len(set)) index := 0 for mode := range set { From c35d5d1b8af675e62babd6fb076e3e33507e243f Mon Sep 17 00:00:00 2001 From: Jeremy Latt Date: Tue, 25 Feb 2014 16:13:47 -0800 Subject: [PATCH 09/10] code review - SEM_VER instead of SEMVER - persist user limit along with other params --- irc/channel.go | 5 +++-- irc/constants.go | 2 +- irc/reply.go | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/irc/channel.go b/irc/channel.go index 26f8909e..d9b73d08 100644 --- a/irc/channel.go +++ b/irc/channel.go @@ -377,8 +377,9 @@ func (channel *Channel) Persist() { channel.server.db.Exec(` INSERT OR REPLACE INTO channel (name, flags, key, topic) - VALUES (?, ?, ?, ?)`, - channel.name, channel.flags.String(), channel.key, channel.topic) + VALUES (?, ?, ?, ?, ?)`, + channel.name, channel.flags.String(), channel.key, channel.topic, + channel.userLimit) } else { channel.server.db.Exec(`DELETE FROM channel WHERE name = ?`, channel.name) } diff --git a/irc/constants.go b/irc/constants.go index 35ff058c..ad1d31fe 100644 --- a/irc/constants.go +++ b/irc/constants.go @@ -23,7 +23,7 @@ var ( ) const ( - SEMVER = "ergonomadic-1.1.0" + SEM_VER = "ergonomadic-1.1.0" CRLF = "\r\n" MAX_REPLY_LEN = 512 - len(CRLF) diff --git a/irc/reply.go b/irc/reply.go index 404a3471..970876fb 100644 --- a/irc/reply.go +++ b/irc/reply.go @@ -151,7 +151,7 @@ func (target *Client) RplWelcome() { func (target *Client) RplYourHost() { target.NumericReply(RPL_YOURHOST, - ":Your host is %s, running version %s", target.server.name, SEMVER) + ":Your host is %s, running version %s", target.server.name, SEM_VER) } func (target *Client) RplCreated() { @@ -161,7 +161,7 @@ func (target *Client) RplCreated() { func (target *Client) RplMyInfo() { target.NumericReply(RPL_MYINFO, - "%s %s aiOorsw abeIikmntpqrsl", target.server.name, SEMVER) + "%s %s aiOorsw abeIikmntpqrsl", target.server.name, SEM_VER) } func (target *Client) RplUModeIs(client *Client) { @@ -371,7 +371,7 @@ func (target *Client) RplWhoisChannels(client *Client) { func (target *Client) RplVersion() { target.NumericReply(RPL_VERSION, - "%s %s", SEMVER, target.server.name) + "%s %s", SEM_VER, target.server.name) } func (target *Client) RplInviting(invitee *Client, channel string) { From 0405c845bd9e89dc14c256e87e3c8359362f639f Mon Sep 17 00:00:00 2001 From: Jeremy Latt Date: Tue, 25 Feb 2014 16:31:41 -0800 Subject: [PATCH 10/10] remove old sql --- sql/drop.sql | 10 ---------- sql/init.sql | 20 -------------------- 2 files changed, 30 deletions(-) delete mode 100644 sql/drop.sql delete mode 100644 sql/init.sql diff --git a/sql/drop.sql b/sql/drop.sql deleted file mode 100644 index b74ab1ba..00000000 --- a/sql/drop.sql +++ /dev/null @@ -1,10 +0,0 @@ -DROP INDEX IF EXISTS index_user_id_channel_id; -DROP TABLE IF EXISTS user_channel; - -DROP INDEX IF EXISTS index_channel_name; -DROP INDEX IF EXISTS index_channel_id; -DROP TABLE IF EXISTS channel; - -DROP INDEX IF EXISTS index_user_nick; -DROP INDEX IF EXISTS index_user_id; -DROP TABLE IF EXISTS user; diff --git a/sql/init.sql b/sql/init.sql deleted file mode 100644 index b73dbffc..00000000 --- a/sql/init.sql +++ /dev/null @@ -1,20 +0,0 @@ -CREATE TABLE user ( - id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - nick TEXT NOT NULL UNIQUE, - hash BLOB NOT NULL -); -CREATE INDEX index_user_id ON user(id); -CREATE INDEX index_user_nick ON user(nick); - -CREATE TABLE channel ( - id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - name TEXT NOT NULL UNIQUE -); -CREATE INDEX index_channel_id ON channel(id); - -CREATE TABLE user_channel ( - id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - user_id INTEGER NOT NULL, - channel_id INTEGER NOT NULL -); -CREATE UNIQUE INDEX index_user_id_channel_id ON user_channel (user_id, channel_id);