mirror of
https://github.com/bettercap/bettercap
synced 2025-07-07 13:32:07 -07:00
Revert "Minor refactors using golint"
This commit is contained in:
parent
9196be7a8b
commit
5328ced392
21 changed files with 101 additions and 70 deletions
|
@ -66,8 +66,9 @@ func ExecSilent(executable string, args []string) (string, error) {
|
||||||
raw, err := exec.Command(path, args...).CombinedOutput()
|
raw, err := exec.Command(path, args...).CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
} else {
|
||||||
|
return Trim(string(raw)), nil
|
||||||
}
|
}
|
||||||
return Trim(string(raw)), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Exec(executable string, args []string) (string, error) {
|
func Exec(executable string, args []string) (string, error) {
|
||||||
|
@ -92,9 +93,10 @@ func ExpandPath(path string) (string, error) {
|
||||||
usr, err := user.Current()
|
usr, err := user.Current()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
} else {
|
||||||
|
// Replace only the first occurrence of ~
|
||||||
|
path = strings.Replace(path, "~", usr.HomeDir, 1)
|
||||||
}
|
}
|
||||||
// Replace only the first occurrence of ~
|
|
||||||
path = strings.Replace(path, "~", usr.HomeDir, 1)
|
|
||||||
}
|
}
|
||||||
return filepath.Abs(path)
|
return filepath.Abs(path)
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,8 +85,9 @@ func (f PfFirewall) enableParam(param string, enabled bool) error {
|
||||||
|
|
||||||
if _, err := f.sysCtlWrite(param, value); err != nil {
|
if _, err := f.sysCtlWrite(param, value); err != nil {
|
||||||
return err
|
return err
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f PfFirewall) EnableForwarding(enabled bool) error {
|
func (f PfFirewall) EnableForwarding(enabled bool) error {
|
||||||
|
|
|
@ -107,8 +107,9 @@ func (s *DNSSpoofer) Configure() error {
|
||||||
for _, domain := range domains {
|
for _, domain := range domains {
|
||||||
if expr, err := glob.Compile(domain); err != nil {
|
if expr, err := glob.Compile(domain); err != nil {
|
||||||
return fmt.Errorf("'%s' is not a valid domain glob expression: %s", domain, err)
|
return fmt.Errorf("'%s' is not a valid domain glob expression: %s", domain, err)
|
||||||
|
} else {
|
||||||
|
s.Domains = append(s.Domains, expr)
|
||||||
}
|
}
|
||||||
s.Domains = append(s.Domains, expr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err, addr = s.StringParam("dns.spoof.address"); err != nil {
|
if err, addr = s.StringParam("dns.spoof.address"); err != nil {
|
||||||
|
|
|
@ -210,8 +210,9 @@ func (s *EventsStream) startWaitingFor(tag string, timeout int) error {
|
||||||
|
|
||||||
if event == nil {
|
if event == nil {
|
||||||
return fmt.Errorf("'events.waitFor %s %d' timed out.", tag, timeout)
|
return fmt.Errorf("'events.waitFor %s %d' timed out.", tag, timeout)
|
||||||
|
} else {
|
||||||
|
log.Debug("Got event: %v", event)
|
||||||
}
|
}
|
||||||
log.Debug("Got event: %v", event)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,8 +98,9 @@ func (gps *GPS) readLine() (line string, err error) {
|
||||||
} else if n == 1 {
|
} else if n == 1 {
|
||||||
if b[0] == '\n' {
|
if b[0] == '\n' {
|
||||||
return core.Trim(line), nil
|
return core.Trim(line), nil
|
||||||
|
} else {
|
||||||
|
line += string(b[0])
|
||||||
}
|
}
|
||||||
line += string(b[0])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,8 +115,9 @@ func (p *HTTPProxy) Configure(address string, proxyPort int, httpPort int, scrip
|
||||||
if scriptPath != "" {
|
if scriptPath != "" {
|
||||||
if err, p.Script = LoadHttpProxyScript(scriptPath, p.sess); err != nil {
|
if err, p.Script = LoadHttpProxyScript(scriptPath, p.sess); err != nil {
|
||||||
return err
|
return err
|
||||||
|
} else {
|
||||||
|
log.Debug("Proxy script %s loaded.", scriptPath)
|
||||||
}
|
}
|
||||||
log.Debug("Proxy script %s loaded.", scriptPath)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Server = &http.Server{
|
p.Server = &http.Server{
|
||||||
|
@ -335,9 +336,9 @@ func (p *HTTPProxy) Stop() error {
|
||||||
p.isRunning = false
|
p.isRunning = false
|
||||||
p.sniListener.Close()
|
p.sniListener.Close()
|
||||||
return nil
|
return nil
|
||||||
|
} else {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
return p.Server.Shutdown(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
return p.Server.Shutdown(ctx)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,9 @@ func (t *CookieTracker) domainOf(req *http.Request) string {
|
||||||
if parsed, err := tld.Parse(req.Host); err != nil {
|
if parsed, err := tld.Parse(req.Host); err != nil {
|
||||||
log.Warning("Could not parse host %s: %s", req.Host, err)
|
log.Warning("Could not parse host %s: %s", req.Host, err)
|
||||||
return req.Host
|
return req.Host
|
||||||
|
} else {
|
||||||
|
return fmt.Sprintf("%s.%s", parsed.Domain, parsed.TLD)
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s.%s", parsed.Domain, parsed.TLD)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *CookieTracker) keyOf(req *http.Request) string {
|
func (t *CookieTracker) keyOf(req *http.Request) string {
|
||||||
|
|
|
@ -304,9 +304,10 @@ func (s *SSLStripper) isMaxRedirs(hostname string) bool {
|
||||||
// reset
|
// reset
|
||||||
delete(s.redirs, hostname)
|
delete(s.redirs, hostname)
|
||||||
return true
|
return true
|
||||||
|
} else {
|
||||||
|
// increment
|
||||||
|
s.redirs[hostname]++
|
||||||
}
|
}
|
||||||
// increment
|
|
||||||
s.redirs[hostname]++
|
|
||||||
} else {
|
} else {
|
||||||
// start tracking redirections
|
// start tracking redirections
|
||||||
s.redirs[hostname] = 1
|
s.redirs[hostname] = 1
|
||||||
|
|
|
@ -71,8 +71,9 @@ func (p *Prober) Configure() error {
|
||||||
var err error
|
var err error
|
||||||
if err, p.throttle = p.IntParam("net.probe.throttle"); err != nil {
|
if err, p.throttle = p.IntParam("net.probe.throttle"); err != nil {
|
||||||
return err
|
return err
|
||||||
|
} else {
|
||||||
|
log.Debug("Throttling packets of %d ms.", p.throttle)
|
||||||
}
|
}
|
||||||
log.Debug("Throttling packets of %d ms.", p.throttle)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,8 +124,9 @@ func (p *TcpProxy) Configure() error {
|
||||||
if scriptPath != "" {
|
if scriptPath != "" {
|
||||||
if err, p.script = LoadTcpProxyScript(scriptPath, p.Session); err != nil {
|
if err, p.script = LoadTcpProxyScript(scriptPath, p.Session); err != nil {
|
||||||
return err
|
return err
|
||||||
|
} else {
|
||||||
|
log.Debug("TCP proxy script %s loaded.", scriptPath)
|
||||||
}
|
}
|
||||||
log.Debug("TCP proxy script %s loaded.", scriptPath)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !p.Session.Firewall.IsForwardingEnabled() {
|
if !p.Session.Firewall.IsForwardingEnabled() {
|
||||||
|
|
|
@ -20,9 +20,9 @@ func findMAC(s *session.Session, ip net.IP, probe bool) (net.HardwareAddr, error
|
||||||
mac, err = network.ArpLookup(s.Interface.Name(), ip.String(), false)
|
mac, err = network.ArpLookup(s.Interface.Name(), ip.String(), false)
|
||||||
if err != nil && probe {
|
if err != nil && probe {
|
||||||
from := s.Interface.IP
|
from := s.Interface.IP
|
||||||
fromHw := s.Interface.HW
|
from_hw := s.Interface.HW
|
||||||
|
|
||||||
if err, probe := packets.NewUDPProbe(from, fromHw, ip, 139); err != nil {
|
if err, probe := packets.NewUDPProbe(from, from_hw, ip, 139); err != nil {
|
||||||
log.Error("Error while creating UDP probe packet for %s: %s", ip.String(), err)
|
log.Error("Error while creating UDP probe packet for %s: %s", ip.String(), err)
|
||||||
} else {
|
} else {
|
||||||
s.Queue.Send(probe)
|
s.Queue.Send(probe)
|
||||||
|
|
|
@ -101,8 +101,9 @@ func NewWiFiModule(s *session.Session) *WiFiModule {
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
if err := w.parseApConfig(); err != nil {
|
if err := w.parseApConfig(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
} else {
|
||||||
|
return w.startAp()
|
||||||
}
|
}
|
||||||
return w.startAp()
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
w.AddParam(session.NewStringParameter("wifi.ap.ssid",
|
w.AddParam(session.NewStringParameter("wifi.ap.ssid",
|
||||||
|
@ -148,8 +149,9 @@ func NewWiFiModule(s *session.Session) *WiFiModule {
|
||||||
// No channels setted, retrieve frequencies supported by the card
|
// No channels setted, retrieve frequencies supported by the card
|
||||||
if frequencies, err := network.GetSupportedFrequencies(w.Session.Interface.Name()); err != nil {
|
if frequencies, err := network.GetSupportedFrequencies(w.Session.Interface.Name()); err != nil {
|
||||||
return err
|
return err
|
||||||
|
} else {
|
||||||
|
newfrequencies = frequencies
|
||||||
}
|
}
|
||||||
newfrequencies = frequencies
|
|
||||||
}
|
}
|
||||||
|
|
||||||
w.frequencies = newfrequencies
|
w.frequencies = newfrequencies
|
||||||
|
|
|
@ -83,30 +83,30 @@ func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) {
|
||||||
recvd,
|
recvd,
|
||||||
seen,
|
seen,
|
||||||
}, include
|
}, include
|
||||||
}
|
} else {
|
||||||
|
// this is ugly, but necessary in order to have this
|
||||||
// this is ugly, but necessary in order to have this
|
// method handle both access point and clients
|
||||||
// method handle both access point and clients
|
// transparently
|
||||||
// transparently
|
clients := ""
|
||||||
clients := ""
|
if ap, found := w.Session.WiFi.Get(station.HwAddress); found {
|
||||||
if ap, found := w.Session.WiFi.Get(station.HwAddress); found {
|
if ap.NumClients() > 0 {
|
||||||
if ap.NumClients() > 0 {
|
clients = strconv.Itoa(ap.NumClients())
|
||||||
clients = strconv.Itoa(ap.NumClients())
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return []string{
|
return []string{
|
||||||
fmt.Sprintf("%d dBm", station.RSSI),
|
fmt.Sprintf("%d dBm", station.RSSI),
|
||||||
bssid,
|
bssid,
|
||||||
ssid,
|
ssid,
|
||||||
/* station.Vendor, */
|
/* station.Vendor, */
|
||||||
encryption,
|
encryption,
|
||||||
strconv.Itoa(network.Dot11Freq2Chan(station.Frequency)),
|
strconv.Itoa(network.Dot11Freq2Chan(station.Frequency)),
|
||||||
clients,
|
clients,
|
||||||
sent,
|
sent,
|
||||||
recvd,
|
recvd,
|
||||||
seen,
|
seen,
|
||||||
}, include
|
}, include
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WiFiModule) Show(by string) error {
|
func (w *WiFiModule) Show(by string) error {
|
||||||
|
|
|
@ -31,8 +31,9 @@ func NewWOL(s *session.Session) *WOL {
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
if mac, err := parseMAC(args); err != nil {
|
if mac, err := parseMAC(args); err != nil {
|
||||||
return err
|
return err
|
||||||
|
} else {
|
||||||
|
return w.wolETH(mac)
|
||||||
}
|
}
|
||||||
return w.wolETH(mac)
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
w.AddHandler(session.NewModuleHandler("wol.udp MAC", "wol.udp(\\s.+)?",
|
w.AddHandler(session.NewModuleHandler("wol.udp MAC", "wol.udp(\\s.+)?",
|
||||||
|
@ -40,8 +41,9 @@ func NewWOL(s *session.Session) *WOL {
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
if mac, err := parseMAC(args); err != nil {
|
if mac, err := parseMAC(args); err != nil {
|
||||||
return err
|
return err
|
||||||
|
} else {
|
||||||
|
return w.wolUDP(mac)
|
||||||
}
|
}
|
||||||
return w.wolUDP(mac)
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
return w
|
return w
|
||||||
|
@ -54,8 +56,9 @@ func parseMAC(args []string) (string, error) {
|
||||||
if tmp != "" {
|
if tmp != "" {
|
||||||
if !reMAC.MatchString(tmp) {
|
if !reMAC.MatchString(tmp) {
|
||||||
return "", fmt.Errorf("%s is not a valid MAC address.", tmp)
|
return "", fmt.Errorf("%s is not a valid MAC address.", tmp)
|
||||||
|
} else {
|
||||||
|
mac = tmp
|
||||||
}
|
}
|
||||||
mac = tmp
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,13 +20,14 @@ func FindGateway(iface *Endpoint) (*Endpoint, error) {
|
||||||
return IPv4RouteIsGateway(iface.Name(), m, func(gateway string) (*Endpoint, error) {
|
return IPv4RouteIsGateway(iface.Name(), m, func(gateway string) (*Endpoint, error) {
|
||||||
if gateway == iface.IpAddress {
|
if gateway == iface.IpAddress {
|
||||||
return iface, nil
|
return iface, nil
|
||||||
|
} else {
|
||||||
|
// we have the address, now we need its mac
|
||||||
|
mac, err := ArpLookup(iface.Name(), gateway, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return NewEndpoint(gateway, mac), nil
|
||||||
}
|
}
|
||||||
// we have the address, now we need its mac
|
|
||||||
mac, err := ArpLookup(iface.Name(), gateway, false)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return NewEndpoint(gateway, mac), nil
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,8 +40,9 @@ func DHCP6For(what dhcp6.MessageType, to dhcp6.Packet, duid []byte) (err error,
|
||||||
var rawCID []byte
|
var rawCID []byte
|
||||||
if raw, found := to.Options[dhcp6.OptionClientID]; !found || len(raw) < 1 {
|
if raw, found := to.Options[dhcp6.OptionClientID]; !found || len(raw) < 1 {
|
||||||
return ErrNoCID, p
|
return ErrNoCID, p
|
||||||
|
} else {
|
||||||
|
rawCID = raw[0]
|
||||||
}
|
}
|
||||||
rawCID = raw[0]
|
|
||||||
|
|
||||||
p.Options.AddRaw(dhcp6.OptionClientID, rawCID)
|
p.Options.AddRaw(dhcp6.OptionClientID, rawCID)
|
||||||
p.Options.AddRaw(dhcp6.OptionServerID, duid)
|
p.Options.AddRaw(dhcp6.OptionServerID, duid)
|
||||||
|
|
|
@ -217,8 +217,9 @@ func (q *Queue) Send(raw []byte) error {
|
||||||
if err := q.handle.WritePacketData(raw); err != nil {
|
if err := q.handle.WritePacketData(raw); err != nil {
|
||||||
q.TrackError()
|
q.TrackError()
|
||||||
return err
|
return err
|
||||||
|
} else {
|
||||||
|
q.TrackSent(uint64(len(raw)))
|
||||||
}
|
}
|
||||||
q.TrackSent(uint64(len(raw)))
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ func (h *CommandHandler) Parse(line string) (bool, []string) {
|
||||||
result := h.Parser.FindStringSubmatch(line)
|
result := h.Parser.FindStringSubmatch(line)
|
||||||
if len(result) == h.Parser.NumSubexp()+1 {
|
if len(result) == h.Parser.NumSubexp()+1 {
|
||||||
return true, result[1:]
|
return true, result[1:]
|
||||||
|
} else {
|
||||||
|
return false, nil
|
||||||
}
|
}
|
||||||
return false, nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,8 +114,9 @@ func (env *Environment) GetInt(name string) (error, int) {
|
||||||
if found, value := env.Get(name); found {
|
if found, value := env.Get(name); found {
|
||||||
if i, err := strconv.Atoi(value); err == nil {
|
if i, err := strconv.Atoi(value); err == nil {
|
||||||
return nil, i
|
return nil, i
|
||||||
|
} else {
|
||||||
|
return err, 0
|
||||||
}
|
}
|
||||||
return err, 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("Not found."), 0
|
return fmt.Errorf("Not found."), 0
|
||||||
|
|
|
@ -62,12 +62,13 @@ func (m SessionModule) ListParam(name string) (err error, values []string) {
|
||||||
list := ""
|
list := ""
|
||||||
if err, list = m.StringParam(name); err != nil {
|
if err, list = m.StringParam(name); err != nil {
|
||||||
return
|
return
|
||||||
}
|
} else {
|
||||||
parts := strings.Split(list, ",")
|
parts := strings.Split(list, ",")
|
||||||
for _, part := range parts {
|
for _, part := range parts {
|
||||||
part = core.Trim(part)
|
part = core.Trim(part)
|
||||||
if part != "" {
|
if part != "" {
|
||||||
values = append(values, part)
|
values = append(values, part)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -77,27 +78,33 @@ func (m SessionModule) StringParam(name string) (error, string) {
|
||||||
if p, found := m.params[name]; found {
|
if p, found := m.params[name]; found {
|
||||||
if err, v := p.Get(m.Session); err != nil {
|
if err, v := p.Get(m.Session); err != nil {
|
||||||
return err, ""
|
return err, ""
|
||||||
|
} else {
|
||||||
|
return nil, v.(string)
|
||||||
}
|
}
|
||||||
return nil, v.(string)
|
} else {
|
||||||
|
return fmt.Errorf("Parameter %s does not exist.", name), ""
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Parameter %s does not exist.", name), ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m SessionModule) IntParam(name string) (error, int) {
|
func (m SessionModule) IntParam(name string) (error, int) {
|
||||||
if p, found := m.params[name]; found {
|
if p, found := m.params[name]; found {
|
||||||
if err, v := p.Get(m.Session); err != nil {
|
if err, v := p.Get(m.Session); err != nil {
|
||||||
return err, 0
|
return err, 0
|
||||||
|
} else {
|
||||||
|
return nil, v.(int)
|
||||||
}
|
}
|
||||||
return nil, v.(int)
|
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("Parameter %s does not exist.", name), 0
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Parameter %s does not exist.", name), 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m SessionModule) BoolParam(name string) (error, bool) {
|
func (m SessionModule) BoolParam(name string) (error, bool) {
|
||||||
if err, v := m.params[name].Get(m.Session); err != nil {
|
if err, v := m.params[name].Get(m.Session); err != nil {
|
||||||
return err, false
|
return err, false
|
||||||
|
} else {
|
||||||
|
return nil, v.(bool)
|
||||||
}
|
}
|
||||||
return nil, v.(bool)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SessionModule) AddHandler(h ModuleHandler) {
|
func (m *SessionModule) AddHandler(h ModuleHandler) {
|
||||||
|
@ -120,8 +127,9 @@ func (m *SessionModule) SetRunning(running bool, cb func()) error {
|
||||||
if running == m.Running() {
|
if running == m.Running() {
|
||||||
if m.Started {
|
if m.Started {
|
||||||
return ErrAlreadyStarted
|
return ErrAlreadyStarted
|
||||||
|
} else {
|
||||||
|
return ErrAlreadyStopped
|
||||||
}
|
}
|
||||||
return ErrAlreadyStopped
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m.StatusLock.Lock()
|
m.StatusLock.Lock()
|
||||||
|
|
|
@ -148,8 +148,9 @@ func (s *Session) sleepHandler(args []string, sess *Session) error {
|
||||||
if secs, err := strconv.Atoi(args[0]); err == nil {
|
if secs, err := strconv.Atoi(args[0]); err == nil {
|
||||||
time.Sleep(time.Duration(secs) * time.Second)
|
time.Sleep(time.Duration(secs) * time.Second)
|
||||||
return nil
|
return nil
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) getHandler(args []string, sess *Session) error {
|
func (s *Session) getHandler(args []string, sess *Session) error {
|
||||||
|
@ -256,8 +257,9 @@ func (s *Session) aliasHandler(args []string, sess *Session) error {
|
||||||
|
|
||||||
if s.Lan.SetAliasFor(mac, alias) {
|
if s.Lan.SetAliasFor(mac, alias) {
|
||||||
return nil
|
return nil
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("Could not find endpoint %s", mac)
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Could not find endpoint %s", mac)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) addHandler(h CommandHandler, c *readline.PrefixCompleter) {
|
func (s *Session) addHandler(h CommandHandler, c *readline.PrefixCompleter) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue