-
Notifications
You must be signed in to change notification settings - Fork 27
/
command.go
83 lines (71 loc) · 2.03 KB
/
command.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package main
import (
"bytes"
"fmt"
"os"
"os/exec"
"strings"
"time"
"github.com/spf13/viper"
"github.com/thoj/go-ircevent"
)
func (i *IRCCat) handleCommand(event *irc.Event) {
msg := event.Message()
channel := ""
respond_to := event.Arguments[0]
if i.inChannel(respond_to) {
channel = respond_to
} else {
respond_to = event.Nick
if !i.authorisedUser(event.Nick) {
log.Infof("Unauthorised command: %s (%s) %s", event.Nick, respond_to, msg)
return
}
}
log.Infof("Authorised command: %s (%s) %s", event.Nick, respond_to, msg)
parts := strings.SplitN(msg, " ", 2)
args := ""
if len(parts) > 1 {
args = parts[1]
}
handler := viper.GetString("commands.handler")
if handler != "" {
cmd := exec.Command(handler)
cmd.Env = append(os.Environ(), fmt.Sprintf("IRCCAT_NICK=%s", event.Nick),
fmt.Sprintf("IRCCAT_USER=%s", event.User),
fmt.Sprintf("IRCCAT_HOST=%s", event.Host),
fmt.Sprintf("IRCCAT_CHANNEL=%s", channel),
fmt.Sprintf("IRCCAT_RESPOND_TO=%s", respond_to),
fmt.Sprintf("IRCCAT_COMMAND=%s", parts[0][1:]),
fmt.Sprintf("IRCCAT_ARGS=%s", args),
fmt.Sprintf("IRCCAT_RAW=%s", event.Raw))
i.runCommand(cmd, respond_to)
}
}
// Run a command with the output going to the nick/channel identified by respond_to
func (i *IRCCat) runCommand(cmd *exec.Cmd, respond_to string) {
var out bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &out
err := cmd.Run()
if err != nil {
log.Errorf("Running command %s failed: %s", cmd.Args, err)
i.irc.Privmsgf(respond_to, "Command failed: %s", err)
}
lines := strings.Split(out.String(), "\n")
line_count := len(lines)
if line_count > viper.GetInt("commands.max_response_lines") {
line_count = viper.GetInt("commands.max_response_lines")
}
for _, line := range lines[0:line_count] {
if line != "" {
// 360 bytes is the worst-case maximum size for PRIVMSG lines. Truncate the lines at that length.
if len(line) > 360 {
line = line[:360]
}
i.irc.Privmsg(respond_to, line)
}
// Pause between lines to avoid being flooded out
time.Sleep(250)
}
}